dttable.c revision 1.1.1.1 1 /******************************************************************************
2 *
3 * Module Name: dttable.c - handling for specific ACPI tables
4 *
5 *****************************************************************************/
6
7 /******************************************************************************
8 *
9 * 1. Copyright Notice
10 *
11 * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
12 * All rights reserved.
13 *
14 * 2. License
15 *
16 * 2.1. This is your license from Intel Corp. under its intellectual property
17 * rights. You may have additional license terms from the party that provided
18 * you this software, covering your right to use that party's intellectual
19 * property rights.
20 *
21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22 * copy of the source code appearing in this file ("Covered Code") an
23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24 * base code distributed originally by Intel ("Original Intel Code") to copy,
25 * make derivatives, distribute, use and display any portion of the Covered
26 * Code in any form, with the right to sublicense such rights; and
27 *
28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29 * license (with the right to sublicense), under only those claims of Intel
30 * patents that are infringed by the Original Intel Code, to make, use, sell,
31 * offer to sell, and import the Covered Code and derivative works thereof
32 * solely to the minimum extent necessary to exercise the above copyright
33 * license, and in no event shall the patent license extend to any additions
34 * to or modifications of the Original Intel Code. No other license or right
35 * is granted directly or by implication, estoppel or otherwise;
36 *
37 * The above copyright and patent license is granted only if the following
38 * conditions are met:
39 *
40 * 3. Conditions
41 *
42 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43 * Redistribution of source code of any substantial portion of the Covered
44 * Code or modification with rights to further distribute source must include
45 * the above Copyright Notice, the above License, this list of Conditions,
46 * and the following Disclaimer and Export Compliance provision. In addition,
47 * Licensee must cause all Covered Code to which Licensee contributes to
48 * contain a file documenting the changes Licensee made to create that Covered
49 * Code and the date of any change. Licensee must include in that file the
50 * documentation of any changes made by any predecessor Licensee. Licensee
51 * must include a prominent statement that the modification is derived,
52 * directly or indirectly, from Original Intel Code.
53 *
54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55 * Redistribution of source code of any substantial portion of the Covered
56 * Code or modification without rights to further distribute source must
57 * include the following Disclaimer and Export Compliance provision in the
58 * documentation and/or other materials provided with distribution. In
59 * addition, Licensee may not authorize further sublicense of source of any
60 * portion of the Covered Code, and must include terms to the effect that the
61 * license from Licensee to its licensee is limited to the intellectual
62 * property embodied in the software Licensee provides to its licensee, and
63 * not to intellectual property embodied in modifications its licensee may
64 * make.
65 *
66 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67 * substantial portion of the Covered Code or modification must reproduce the
68 * above Copyright Notice, and the following Disclaimer and Export Compliance
69 * provision in the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3.4. Intel retains all right, title, and interest in and to the Original
73 * Intel Code.
74 *
75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76 * Intel shall be used in advertising or otherwise to promote the sale, use or
77 * other dealings in products derived from or relating to the Covered Code
78 * without prior written authorization from Intel.
79 *
80 * 4. Disclaimer and Export Compliance
81 *
82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88 * PARTICULAR PURPOSE.
89 *
90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97 * LIMITED REMEDY.
98 *
99 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100 * software or system incorporating such software without first obtaining any
101 * required license or other approval from the U. S. Department of Commerce or
102 * any other agency or department of the United States Government. In the
103 * event Licensee exports any such software from the United States or
104 * re-exports any such software from a foreign destination, Licensee shall
105 * ensure that the distribution and export/re-export of the software is in
106 * compliance with all laws, regulations, orders, or other restrictions of the
107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108 * any of its subsidiaries will export/re-export any technical data, process,
109 * software, or service, directly or indirectly, to any country for which the
110 * United States government or any agency thereof requires an export license,
111 * other governmental approval, or letter of assurance, without first obtaining
112 * such license, approval or letter.
113 *
114 *****************************************************************************/
115
116 #define __DTTABLE_C__
117
118 /* Compile all complex data tables */
119
120 #include "aslcompiler.h"
121 #include "dtcompiler.h"
122
123 #define _COMPONENT DT_COMPILER
124 ACPI_MODULE_NAME ("dttable")
125
126
127 /* TBD: merge these into dmtbinfo.c? */
128
129 static ACPI_DMTABLE_INFO TableInfoAsfAddress[] =
130 {
131 {ACPI_DMT_BUFFER, 0, "Addresses", 0},
132 {ACPI_DMT_EXIT, 0, NULL, 0}
133 };
134
135 static ACPI_DMTABLE_INFO TableInfoDmarPciPath[] =
136 {
137 {ACPI_DMT_PCI_PATH, 0, "PCI Path", 0},
138 {ACPI_DMT_EXIT, 0, NULL, 0}
139 };
140
141
142 /* TBD: move to acmacros.h */
143
144 #define ACPI_SUB_PTR(t, a, b) \
145 ACPI_CAST_PTR (t, (ACPI_CAST_PTR (UINT8, (a)) - (ACPI_SIZE)(b)))
146
147
148 /* Local prototypes */
149
150 static ACPI_STATUS
151 DtCompileTwoSubtables (
152 void **List,
153 ACPI_DMTABLE_INFO *TableInfo1,
154 ACPI_DMTABLE_INFO *TableInfo2);
155
156
157 /******************************************************************************
158 *
159 * FUNCTION: DtCompileTwoSubtables
160 *
161 * PARAMETERS: List - Current field list pointer
162 * TableInfo1 - Info table 1
163 * TableInfo1 - Info table 2
164 *
165 * RETURN: Status
166 *
167 * DESCRIPTION: Compile tables with a header and one or more same subtables.
168 * Include CPEP, EINJ, ERST, MCFG, MSCT, WDAT
169 *
170 *****************************************************************************/
171
172 static ACPI_STATUS
173 DtCompileTwoSubtables (
174 void **List,
175 ACPI_DMTABLE_INFO *TableInfo1,
176 ACPI_DMTABLE_INFO *TableInfo2)
177 {
178 ACPI_STATUS Status;
179 DT_SUBTABLE *Subtable;
180 DT_SUBTABLE *ParentTable;
181 DT_FIELD **PFieldList = (DT_FIELD **) List;
182
183
184 Status = DtCompileTable (PFieldList, TableInfo1, &Subtable, TRUE);
185 if (ACPI_FAILURE (Status))
186 {
187 return (Status);
188 }
189
190 ParentTable = DtPeekSubtable ();
191 DtInsertSubtable (ParentTable, Subtable);
192
193 while (*PFieldList)
194 {
195 Status = DtCompileTable (PFieldList, TableInfo2, &Subtable, FALSE);
196 if (ACPI_FAILURE (Status))
197 {
198 return (Status);
199 }
200
201 DtInsertSubtable (ParentTable, Subtable);
202 }
203
204 return (AE_OK);
205 }
206
207
208 /******************************************************************************
209 *
210 * FUNCTION: DtCompileFacs
211 *
212 * PARAMETERS: PFieldList - Current field list pointer
213 *
214 * RETURN: Status
215 *
216 * DESCRIPTION: Compile FACS.
217 *
218 *****************************************************************************/
219
220 ACPI_STATUS
221 DtCompileFacs (
222 DT_FIELD **PFieldList)
223 {
224 DT_SUBTABLE *Subtable;
225 UINT8 *ReservedBuffer;
226 ACPI_STATUS Status;
227 UINT32 ReservedSize;
228
229
230 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFacs,
231 &Gbl_RootTable, TRUE);
232 if (ACPI_FAILURE (Status))
233 {
234 return (Status);
235 }
236
237 /* Large FACS reserved area at the end of the table */
238
239 ReservedSize = (UINT32) sizeof (((ACPI_TABLE_FACS *) NULL)->Reserved1);
240 ReservedBuffer = UtLocalCalloc (ReservedSize);
241
242 DtCreateSubtable (ReservedBuffer, ReservedSize, &Subtable);
243
244 ACPI_FREE (ReservedBuffer);
245 DtInsertSubtable (Gbl_RootTable, Subtable);
246 return (AE_OK);
247 }
248
249
250 /******************************************************************************
251 *
252 * FUNCTION: DtCompileRsdp
253 *
254 * PARAMETERS: PFieldList - Current field list pointer
255 *
256 * RETURN: Status
257 *
258 * DESCRIPTION: Compile RSDP.
259 *
260 *****************************************************************************/
261
262 ACPI_STATUS
263 DtCompileRsdp (
264 DT_FIELD **PFieldList)
265 {
266 DT_SUBTABLE *Subtable;
267 ACPI_TABLE_RSDP *Table;
268 ACPI_STATUS Status;
269
270
271 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp1,
272 &Gbl_RootTable, TRUE);
273 if (ACPI_FAILURE (Status))
274 {
275 return (Status);
276 }
277
278 Table = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Gbl_RootTable->Buffer);
279 DtSetTableChecksum (&Table->Checksum);
280
281 if (Table->Revision > 0)
282 {
283 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp2,
284 &Subtable, TRUE);
285 if (ACPI_FAILURE (Status))
286 {
287 return (Status);
288 }
289
290 DtInsertSubtable (Gbl_RootTable, Subtable);
291 DtSetTableChecksum (&Table->ExtendedChecksum);
292 }
293
294 return (AE_OK);
295 }
296
297
298 /******************************************************************************
299 *
300 * FUNCTION: DtCompileAsf
301 *
302 * PARAMETERS: List - Current field list pointer
303 *
304 * RETURN: Status
305 *
306 * DESCRIPTION: Compile ASF!.
307 *
308 *****************************************************************************/
309
310 ACPI_STATUS
311 DtCompileAsf (
312 void **List)
313 {
314 ACPI_ASF_INFO *AsfTable;
315 DT_SUBTABLE *Subtable;
316 DT_SUBTABLE *ParentTable;
317 ACPI_DMTABLE_INFO *InfoTable;
318 ACPI_DMTABLE_INFO *DataInfoTable = NULL;
319 UINT32 DataCount = 0;
320 ACPI_STATUS Status;
321 UINT32 i;
322 DT_FIELD **PFieldList = (DT_FIELD **) List;
323 DT_FIELD *SubtableStart;
324
325
326 while (*PFieldList)
327 {
328 SubtableStart = *PFieldList;
329 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr,
330 &Subtable, TRUE);
331 if (ACPI_FAILURE (Status))
332 {
333 return (Status);
334 }
335
336 ParentTable = DtPeekSubtable ();
337 DtInsertSubtable (ParentTable, Subtable);
338 DtPushSubtable (Subtable);
339
340 AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer);
341
342 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
343 {
344 case ACPI_ASF_TYPE_INFO:
345 InfoTable = AcpiDmTableInfoAsf0;
346 break;
347
348 case ACPI_ASF_TYPE_ALERT:
349 InfoTable = AcpiDmTableInfoAsf1;
350 break;
351
352 case ACPI_ASF_TYPE_CONTROL:
353 InfoTable = AcpiDmTableInfoAsf2;
354 break;
355
356 case ACPI_ASF_TYPE_BOOT:
357 InfoTable = AcpiDmTableInfoAsf3;
358 break;
359
360 case ACPI_ASF_TYPE_ADDRESS:
361 InfoTable = AcpiDmTableInfoAsf4;
362 break;
363
364 default:
365 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
366 return (AE_ERROR);
367 }
368
369 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
370 if (ACPI_FAILURE (Status))
371 {
372 return (Status);
373 }
374
375 ParentTable = DtPeekSubtable ();
376 DtInsertSubtable (ParentTable, Subtable);
377
378 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
379 {
380 case ACPI_ASF_TYPE_INFO:
381 DataInfoTable = NULL;
382 break;
383
384 case ACPI_ASF_TYPE_ALERT:
385 DataInfoTable = AcpiDmTableInfoAsf1a;
386 DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT,
387 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
388 sizeof (ACPI_ASF_HEADER)))->Alerts;
389 break;
390
391 case ACPI_ASF_TYPE_CONTROL:
392 DataInfoTable = AcpiDmTableInfoAsf2a;
393 DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE,
394 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
395 sizeof (ACPI_ASF_HEADER)))->Controls;
396 break;
397
398 case ACPI_ASF_TYPE_BOOT:
399 DataInfoTable = NULL;
400 break;
401
402 case ACPI_ASF_TYPE_ADDRESS:
403 DataInfoTable = TableInfoAsfAddress;
404 DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS,
405 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
406 sizeof (ACPI_ASF_HEADER)))->Devices;
407 break;
408
409 default:
410 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
411 return (AE_ERROR);
412 }
413
414 if (DataInfoTable)
415 {
416 switch (AsfTable->Header.Type & 0x7F)
417 {
418 case ACPI_ASF_TYPE_ADDRESS:
419
420 while (DataCount > 0)
421 {
422 Status = DtCompileTable (PFieldList, DataInfoTable,
423 &Subtable, TRUE);
424 if (ACPI_FAILURE (Status))
425 {
426 return (Status);
427 }
428
429 DtInsertSubtable (ParentTable, Subtable);
430 DataCount = DataCount - Subtable->Length;
431 }
432 break;
433
434 default:
435
436 for (i = 0; i < DataCount; i++)
437 {
438 Status = DtCompileTable (PFieldList, DataInfoTable,
439 &Subtable, TRUE);
440 if (ACPI_FAILURE (Status))
441 {
442 return (Status);
443 }
444
445 DtInsertSubtable (ParentTable, Subtable);
446 }
447 break;
448 }
449 }
450
451 DtPopSubtable ();
452 }
453
454 return (AE_OK);
455 }
456
457
458 /******************************************************************************
459 *
460 * FUNCTION: DtCompileCpep
461 *
462 * PARAMETERS: List - Current field list pointer
463 *
464 * RETURN: Status
465 *
466 * DESCRIPTION: Compile CPEP.
467 *
468 *****************************************************************************/
469
470 ACPI_STATUS
471 DtCompileCpep (
472 void **List)
473 {
474 ACPI_STATUS Status;
475
476
477 Status = DtCompileTwoSubtables (List,
478 AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
479 return (Status);
480 }
481
482
483 /******************************************************************************
484 *
485 * FUNCTION: DtCompileDmar
486 *
487 * PARAMETERS: List - Current field list pointer
488 *
489 * RETURN: Status
490 *
491 * DESCRIPTION: Compile DMAR.
492 *
493 *****************************************************************************/
494
495 ACPI_STATUS
496 DtCompileDmar (
497 void **List)
498 {
499 ACPI_STATUS Status;
500 DT_SUBTABLE *Subtable;
501 DT_SUBTABLE *ParentTable;
502 DT_FIELD **PFieldList = (DT_FIELD **) List;
503 DT_FIELD *SubtableStart;
504 ACPI_DMTABLE_INFO *InfoTable;
505 ACPI_DMAR_HEADER *DmarHeader;
506 UINT8 *ReservedBuffer;
507 UINT32 ReservedSize;
508
509
510 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable, TRUE);
511 if (ACPI_FAILURE (Status))
512 {
513 return (Status);
514 }
515
516 ParentTable = DtPeekSubtable ();
517 DtInsertSubtable (ParentTable, Subtable);
518
519 /* DMAR Reserved area */
520
521 ReservedSize = (UINT32) sizeof (((ACPI_TABLE_DMAR *) NULL)->Reserved);
522 ReservedBuffer = UtLocalCalloc (ReservedSize);
523
524 DtCreateSubtable (ReservedBuffer, ReservedSize, &Subtable);
525
526 ACPI_FREE (ReservedBuffer);
527 ParentTable = DtPeekSubtable ();
528 DtInsertSubtable (ParentTable, Subtable);
529
530 while (*PFieldList)
531 {
532 /* DMAR Header */
533
534 SubtableStart = *PFieldList;
535 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
536 &Subtable, TRUE);
537 if (ACPI_FAILURE (Status))
538 {
539 return (Status);
540 }
541
542 ParentTable = DtPeekSubtable ();
543 DtInsertSubtable (ParentTable, Subtable);
544 DtPushSubtable (Subtable);
545
546 DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
547
548 switch (DmarHeader->Type)
549 {
550 case ACPI_DMAR_TYPE_HARDWARE_UNIT:
551 InfoTable = AcpiDmTableInfoDmar0;
552 break;
553 case ACPI_DMAR_TYPE_RESERVED_MEMORY:
554 InfoTable = AcpiDmTableInfoDmar1;
555 break;
556 case ACPI_DMAR_TYPE_ATSR:
557 InfoTable = AcpiDmTableInfoDmar2;
558 break;
559 case ACPI_DMAR_HARDWARE_AFFINITY:
560 InfoTable = AcpiDmTableInfoDmar3;
561 break;
562 default:
563 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
564 return (AE_ERROR);
565 }
566
567 /* DMAR Subtable */
568
569 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
570 if (ACPI_FAILURE (Status))
571 {
572 return (Status);
573 }
574
575 ParentTable = DtPeekSubtable ();
576 DtInsertSubtable (ParentTable, Subtable);
577
578 /* Optional Device Scope subtables */
579
580 while (*PFieldList)
581 {
582 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
583 &Subtable, FALSE);
584 if (Status == AE_NOT_FOUND)
585 {
586 break;
587 }
588
589 ParentTable = DtPeekSubtable ();
590 DtInsertSubtable (ParentTable, Subtable);
591 DtPushSubtable (Subtable);
592
593 /* Optional PCI Paths */
594
595 while (*PFieldList)
596 {
597 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
598 &Subtable, FALSE);
599 if (Status == AE_NOT_FOUND)
600 {
601 DtPopSubtable ();
602 break;
603 }
604
605 ParentTable = DtPeekSubtable ();
606 DtInsertSubtable (ParentTable, Subtable);
607 }
608 }
609
610 DtPopSubtable ();
611 }
612
613 return (AE_OK);
614 }
615
616
617 /******************************************************************************
618 *
619 * FUNCTION: DtCompileEinj
620 *
621 * PARAMETERS: List - Current field list pointer
622 *
623 * RETURN: Status
624 *
625 * DESCRIPTION: Compile EINJ.
626 *
627 *****************************************************************************/
628
629 ACPI_STATUS
630 DtCompileEinj (
631 void **List)
632 {
633 ACPI_STATUS Status;
634
635
636 Status = DtCompileTwoSubtables (List,
637 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
638 return (Status);
639 }
640
641
642 /******************************************************************************
643 *
644 * FUNCTION: DtCompileErst
645 *
646 * PARAMETERS: List - Current field list pointer
647 *
648 * RETURN: Status
649 *
650 * DESCRIPTION: Compile ERST.
651 *
652 *****************************************************************************/
653
654 ACPI_STATUS
655 DtCompileErst (
656 void **List)
657 {
658 ACPI_STATUS Status;
659
660
661 Status = DtCompileTwoSubtables (List,
662 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
663 return (Status);
664 }
665
666
667 /******************************************************************************
668 *
669 * FUNCTION: DtCompileFadt
670 *
671 * PARAMETERS: List - Current field list pointer
672 *
673 * RETURN: Status
674 *
675 * DESCRIPTION: Compile FADT.
676 *
677 *****************************************************************************/
678
679 ACPI_STATUS
680 DtCompileFadt (
681 void **List)
682 {
683 ACPI_STATUS Status;
684 DT_SUBTABLE *Subtable;
685 DT_SUBTABLE *ParentTable;
686 DT_FIELD **PFieldList = (DT_FIELD **) List;
687 ACPI_TABLE_HEADER *Table;
688 UINT8 Revision;
689
690
691 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt1,
692 &Subtable, TRUE);
693 if (ACPI_FAILURE (Status))
694 {
695 return (Status);
696 }
697
698 ParentTable = DtPeekSubtable ();
699 DtInsertSubtable (ParentTable, Subtable);
700
701 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
702 Revision = Table->Revision;
703
704 if (Revision == 2)
705 {
706 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt2,
707 &Subtable, TRUE);
708 if (ACPI_FAILURE (Status))
709 {
710 return (Status);
711 }
712
713 DtInsertSubtable (ParentTable, Subtable);
714 }
715 else if (Revision >= 2)
716 {
717 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt3,
718 &Subtable, TRUE);
719 if (ACPI_FAILURE (Status))
720 {
721 return (Status);
722 }
723
724 DtInsertSubtable (ParentTable, Subtable);
725 }
726
727 return (AE_OK);
728 }
729
730
731 /******************************************************************************
732 *
733 * FUNCTION: DtCompileHest
734 *
735 * PARAMETERS: List - Current field list pointer
736 *
737 * RETURN: Status
738 *
739 * DESCRIPTION: Compile HEST.
740 *
741 *****************************************************************************/
742
743 ACPI_STATUS
744 DtCompileHest (
745 void **List)
746 {
747 ACPI_STATUS Status;
748 DT_SUBTABLE *Subtable;
749 DT_SUBTABLE *ParentTable;
750 DT_FIELD **PFieldList = (DT_FIELD **) List;
751 DT_FIELD *SubtableStart;
752 ACPI_DMTABLE_INFO *InfoTable;
753 UINT16 Type;
754 UINT32 BankCount;
755
756
757 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
758 &Subtable, TRUE);
759 if (ACPI_FAILURE (Status))
760 {
761 return (Status);
762 }
763
764 ParentTable = DtPeekSubtable ();
765 DtInsertSubtable (ParentTable, Subtable);
766
767 while (*PFieldList)
768 {
769 /* Get subtable type */
770
771 SubtableStart = *PFieldList;
772 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
773
774 switch (Type)
775 {
776 case ACPI_HEST_TYPE_IA32_CHECK:
777 InfoTable = AcpiDmTableInfoHest0;
778 break;
779
780 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
781 InfoTable = AcpiDmTableInfoHest1;
782 break;
783
784 case ACPI_HEST_TYPE_IA32_NMI:
785 InfoTable = AcpiDmTableInfoHest2;
786 break;
787
788 case ACPI_HEST_TYPE_AER_ROOT_PORT:
789 InfoTable = AcpiDmTableInfoHest6;
790 break;
791
792 case ACPI_HEST_TYPE_AER_ENDPOINT:
793 InfoTable = AcpiDmTableInfoHest7;
794 break;
795
796 case ACPI_HEST_TYPE_AER_BRIDGE:
797 InfoTable = AcpiDmTableInfoHest8;
798 break;
799
800 case ACPI_HEST_TYPE_GENERIC_ERROR:
801 InfoTable = AcpiDmTableInfoHest9;
802 break;
803
804 default:
805 /* Cannot continue on unknown type */
806
807 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
808 return (AE_ERROR);
809 }
810
811 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
812 if (ACPI_FAILURE (Status))
813 {
814 return (Status);
815 }
816
817 DtInsertSubtable (ParentTable, Subtable);
818
819 /*
820 * Additional subtable data - IA32 Error Bank(s)
821 */
822 BankCount = 0;
823 switch (Type)
824 {
825 case ACPI_HEST_TYPE_IA32_CHECK:
826 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
827 Subtable->Buffer))->NumHardwareBanks;
828 break;
829
830 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
831 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
832 Subtable->Buffer))->NumHardwareBanks;
833 break;
834
835 default:
836 break;
837 }
838
839 while (BankCount)
840 {
841 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
842 &Subtable, TRUE);
843 if (ACPI_FAILURE (Status))
844 {
845 return (Status);
846 }
847
848 DtInsertSubtable (ParentTable, Subtable);
849 BankCount--;
850 }
851 }
852
853 return AE_OK;
854 }
855
856
857 /******************************************************************************
858 *
859 * FUNCTION: DtCompileIvrs
860 *
861 * PARAMETERS: List - Current field list pointer
862 *
863 * RETURN: Status
864 *
865 * DESCRIPTION: Compile IVRS.
866 *
867 *****************************************************************************/
868
869 ACPI_STATUS
870 DtCompileIvrs (
871 void **List)
872 {
873 ACPI_STATUS Status;
874 DT_SUBTABLE *Subtable;
875 DT_SUBTABLE *ParentTable;
876 DT_FIELD **PFieldList = (DT_FIELD **) List;
877 DT_FIELD *SubtableStart;
878 ACPI_DMTABLE_INFO *InfoTable;
879 ACPI_IVRS_HEADER *IvrsHeader;
880 UINT8 EntryType;
881
882
883 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
884 &Subtable, TRUE);
885 if (ACPI_FAILURE (Status))
886 {
887 return (Status);
888 }
889
890 ParentTable = DtPeekSubtable ();
891 DtInsertSubtable (ParentTable, Subtable);
892
893 while (*PFieldList)
894 {
895 SubtableStart = *PFieldList;
896 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr,
897 &Subtable, TRUE);
898 if (ACPI_FAILURE (Status))
899 {
900 return (Status);
901 }
902
903 ParentTable = DtPeekSubtable ();
904 DtInsertSubtable (ParentTable, Subtable);
905 DtPushSubtable (Subtable);
906
907 IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer);
908
909 switch (IvrsHeader->Type)
910 {
911 case ACPI_IVRS_TYPE_HARDWARE:
912 InfoTable = AcpiDmTableInfoIvrs0;
913 break;
914
915 case ACPI_IVRS_TYPE_MEMORY1:
916 case ACPI_IVRS_TYPE_MEMORY2:
917 case ACPI_IVRS_TYPE_MEMORY3:
918 InfoTable = AcpiDmTableInfoIvrs1;
919 break;
920
921 default:
922 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS");
923 return (AE_ERROR);
924 }
925
926 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
927 if (ACPI_FAILURE (Status))
928 {
929 return (Status);
930 }
931
932 ParentTable = DtPeekSubtable ();
933 DtInsertSubtable (ParentTable, Subtable);
934
935 if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE)
936 {
937 while (*PFieldList &&
938 !ACPI_STRCMP ((*PFieldList)->Name, "Entry Type"))
939 {
940 SubtableStart = *PFieldList;
941 DtCompileInteger (&EntryType, *PFieldList, 1, 0);
942
943 switch (EntryType)
944 {
945 /* 4-byte device entries */
946
947 case ACPI_IVRS_TYPE_PAD4:
948 case ACPI_IVRS_TYPE_ALL:
949 case ACPI_IVRS_TYPE_SELECT:
950 case ACPI_IVRS_TYPE_START:
951 case ACPI_IVRS_TYPE_END:
952
953 InfoTable = AcpiDmTableInfoIvrs4;
954 break;
955
956 /* 8-byte entries, type A */
957
958 case ACPI_IVRS_TYPE_ALIAS_SELECT:
959 case ACPI_IVRS_TYPE_ALIAS_START:
960
961 InfoTable = AcpiDmTableInfoIvrs8a;
962 break;
963
964 /* 8-byte entries, type B */
965
966 case ACPI_IVRS_TYPE_PAD8:
967 case ACPI_IVRS_TYPE_EXT_SELECT:
968 case ACPI_IVRS_TYPE_EXT_START:
969
970 InfoTable = AcpiDmTableInfoIvrs8b;
971 break;
972
973 /* 8-byte entries, type C */
974
975 case ACPI_IVRS_TYPE_SPECIAL:
976
977 InfoTable = AcpiDmTableInfoIvrs8c;
978 break;
979
980 default:
981 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
982 "IVRS Device Entry");
983 return (AE_ERROR);
984 }
985
986 Status = DtCompileTable (PFieldList, InfoTable,
987 &Subtable, TRUE);
988 if (ACPI_FAILURE (Status))
989 {
990 return (Status);
991 }
992
993 DtInsertSubtable (ParentTable, Subtable);
994 }
995 }
996
997 DtPopSubtable ();
998 }
999
1000 return (AE_OK);
1001 }
1002
1003
1004 /******************************************************************************
1005 *
1006 * FUNCTION: DtCompileMadt
1007 *
1008 * PARAMETERS: List - Current field list pointer
1009 *
1010 * RETURN: Status
1011 *
1012 * DESCRIPTION: Compile MADT.
1013 *
1014 *****************************************************************************/
1015
1016 ACPI_STATUS
1017 DtCompileMadt (
1018 void **List)
1019 {
1020 ACPI_STATUS Status;
1021 DT_SUBTABLE *Subtable;
1022 DT_SUBTABLE *ParentTable;
1023 DT_FIELD **PFieldList = (DT_FIELD **) List;
1024 DT_FIELD *SubtableStart;
1025 ACPI_SUBTABLE_HEADER *MadtHeader;
1026 ACPI_DMTABLE_INFO *InfoTable;
1027
1028
1029 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt,
1030 &Subtable, TRUE);
1031 if (ACPI_FAILURE (Status))
1032 {
1033 return (Status);
1034 }
1035
1036 ParentTable = DtPeekSubtable ();
1037 DtInsertSubtable (ParentTable, Subtable);
1038
1039 while (*PFieldList)
1040 {
1041 SubtableStart = *PFieldList;
1042 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr,
1043 &Subtable, TRUE);
1044 if (ACPI_FAILURE (Status))
1045 {
1046 return (Status);
1047 }
1048
1049 ParentTable = DtPeekSubtable ();
1050 DtInsertSubtable (ParentTable, Subtable);
1051 DtPushSubtable (Subtable);
1052
1053 MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1054
1055 switch (MadtHeader->Type)
1056 {
1057 case ACPI_MADT_TYPE_LOCAL_APIC:
1058 InfoTable = AcpiDmTableInfoMadt0;
1059 break;
1060 case ACPI_MADT_TYPE_IO_APIC:
1061 InfoTable = AcpiDmTableInfoMadt1;
1062 break;
1063 case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
1064 InfoTable = AcpiDmTableInfoMadt2;
1065 break;
1066 case ACPI_MADT_TYPE_NMI_SOURCE:
1067 InfoTable = AcpiDmTableInfoMadt3;
1068 break;
1069 case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
1070 InfoTable = AcpiDmTableInfoMadt4;
1071 break;
1072 case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
1073 InfoTable = AcpiDmTableInfoMadt5;
1074 break;
1075 case ACPI_MADT_TYPE_IO_SAPIC:
1076 InfoTable = AcpiDmTableInfoMadt6;
1077 break;
1078 case ACPI_MADT_TYPE_LOCAL_SAPIC:
1079 InfoTable = AcpiDmTableInfoMadt7;
1080 break;
1081 case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
1082 InfoTable = AcpiDmTableInfoMadt8;
1083 break;
1084 case ACPI_MADT_TYPE_LOCAL_X2APIC:
1085 InfoTable = AcpiDmTableInfoMadt9;
1086 break;
1087 case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
1088 InfoTable = AcpiDmTableInfoMadt10;
1089 break;
1090 default:
1091 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT");
1092 return (AE_ERROR);
1093 }
1094
1095 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1096 if (ACPI_FAILURE (Status))
1097 {
1098 return (Status);
1099 }
1100
1101 ParentTable = DtPeekSubtable ();
1102 DtInsertSubtable (ParentTable, Subtable);
1103 DtPopSubtable ();
1104 }
1105
1106 return (AE_OK);
1107 }
1108
1109
1110 /******************************************************************************
1111 *
1112 * FUNCTION: DtCompileMcfg
1113 *
1114 * PARAMETERS: List - Current field list pointer
1115 *
1116 * RETURN: Status
1117 *
1118 * DESCRIPTION: Compile MCFG.
1119 *
1120 *****************************************************************************/
1121
1122 ACPI_STATUS
1123 DtCompileMcfg (
1124 void **List)
1125 {
1126 ACPI_STATUS Status;
1127
1128
1129 Status = DtCompileTwoSubtables (List,
1130 AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0);
1131 return (Status);
1132 }
1133
1134
1135 /******************************************************************************
1136 *
1137 * FUNCTION: DtCompileMsct
1138 *
1139 * PARAMETERS: List - Current field list pointer
1140 *
1141 * RETURN: Status
1142 *
1143 * DESCRIPTION: Compile MSCT.
1144 *
1145 *****************************************************************************/
1146
1147 ACPI_STATUS
1148 DtCompileMsct (
1149 void **List)
1150 {
1151 ACPI_STATUS Status;
1152
1153
1154 Status = DtCompileTwoSubtables (List,
1155 AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0);
1156 return (Status);
1157 }
1158
1159
1160 /******************************************************************************
1161 *
1162 * FUNCTION: DtCompileRsdt
1163 *
1164 * PARAMETERS: List - Current field list pointer
1165 *
1166 * RETURN: Status
1167 *
1168 * DESCRIPTION: Compile RSDT.
1169 *
1170 *****************************************************************************/
1171
1172 ACPI_STATUS
1173 DtCompileRsdt (
1174 void **List)
1175 {
1176 DT_SUBTABLE *Subtable;
1177 DT_SUBTABLE *ParentTable;
1178 DT_FIELD *FieldList = *(DT_FIELD **) List;
1179 UINT32 Address;
1180
1181
1182 ParentTable = DtPeekSubtable ();
1183
1184 while (FieldList)
1185 {
1186 DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
1187
1188 DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
1189 DtInsertSubtable (ParentTable, Subtable);
1190 FieldList = FieldList->Next;
1191 }
1192
1193 return (AE_OK);
1194 }
1195
1196
1197 /******************************************************************************
1198 *
1199 * FUNCTION: DtCompileSlit
1200 *
1201 * PARAMETERS: List - Current field list pointer
1202 *
1203 * RETURN: Status
1204 *
1205 * DESCRIPTION: Compile SLIT.
1206 *
1207 *****************************************************************************/
1208
1209 ACPI_STATUS
1210 DtCompileSlit (
1211 void **List)
1212 {
1213 ACPI_STATUS Status;
1214 DT_SUBTABLE *Subtable;
1215 DT_SUBTABLE *ParentTable;
1216 DT_FIELD **PFieldList = (DT_FIELD **) List;
1217 DT_FIELD *FieldList;
1218 UINT32 Localities;
1219 UINT8 *LocalityBuffer;
1220 UINT32 RemainingData;
1221
1222
1223 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
1224 &Subtable, TRUE);
1225 if (ACPI_FAILURE (Status))
1226 {
1227 return (Status);
1228 }
1229
1230 ParentTable = DtPeekSubtable ();
1231 DtInsertSubtable (ParentTable, Subtable);
1232
1233 Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
1234 LocalityBuffer = UtLocalCalloc (Localities);
1235
1236 FieldList = *PFieldList;
1237 while (FieldList)
1238 {
1239 /* Handle multiple-line buffer */
1240
1241 RemainingData = Localities;
1242 while (RemainingData && FieldList)
1243 {
1244 RemainingData = DtCompileBuffer (
1245 LocalityBuffer + (Localities - RemainingData),
1246 FieldList->Value, FieldList, RemainingData);
1247 FieldList = FieldList->Next;
1248 }
1249
1250 DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
1251 DtInsertSubtable (ParentTable, Subtable);
1252 }
1253
1254 ACPI_FREE (LocalityBuffer);
1255 return (AE_OK);
1256 }
1257
1258
1259 /******************************************************************************
1260 *
1261 * FUNCTION: DtCompileSrat
1262 *
1263 * PARAMETERS: List - Current field list pointer
1264 *
1265 * RETURN: Status
1266 *
1267 * DESCRIPTION: Compile SRAT.
1268 *
1269 *****************************************************************************/
1270
1271 ACPI_STATUS
1272 DtCompileSrat (
1273 void **List)
1274 {
1275 ACPI_STATUS Status;
1276 DT_SUBTABLE *Subtable;
1277 DT_SUBTABLE *ParentTable;
1278 DT_FIELD **PFieldList = (DT_FIELD **) List;
1279 DT_FIELD *SubtableStart;
1280 ACPI_SUBTABLE_HEADER *SratHeader;
1281 ACPI_DMTABLE_INFO *InfoTable;
1282
1283
1284 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
1285 &Subtable, TRUE);
1286 if (ACPI_FAILURE (Status))
1287 {
1288 return (Status);
1289 }
1290
1291 ParentTable = DtPeekSubtable ();
1292 DtInsertSubtable (ParentTable, Subtable);
1293
1294 while (*PFieldList)
1295 {
1296 SubtableStart = *PFieldList;
1297 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
1298 &Subtable, TRUE);
1299 if (ACPI_FAILURE (Status))
1300 {
1301 return (Status);
1302 }
1303
1304 ParentTable = DtPeekSubtable ();
1305 DtInsertSubtable (ParentTable, Subtable);
1306 DtPushSubtable (Subtable);
1307
1308 SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1309
1310 switch (SratHeader->Type)
1311 {
1312 case ACPI_SRAT_TYPE_CPU_AFFINITY:
1313 InfoTable = AcpiDmTableInfoSrat0;
1314 break;
1315 case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
1316 InfoTable = AcpiDmTableInfoSrat1;
1317 break;
1318 case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
1319 InfoTable = AcpiDmTableInfoSrat2;
1320 break;
1321 default:
1322 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
1323 return (AE_ERROR);
1324 }
1325
1326 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1327 if (ACPI_FAILURE (Status))
1328 {
1329 return (Status);
1330 }
1331
1332 ParentTable = DtPeekSubtable ();
1333 DtInsertSubtable (ParentTable, Subtable);
1334 DtPopSubtable ();
1335 }
1336
1337 return (AE_OK);
1338 }
1339
1340
1341 /******************************************************************************
1342 *
1343 * FUNCTION: DtCompileWdat
1344 *
1345 * PARAMETERS: List - Current field list pointer
1346 *
1347 * RETURN: Status
1348 *
1349 * DESCRIPTION: Compile WDAT.
1350 *
1351 *****************************************************************************/
1352
1353 ACPI_STATUS
1354 DtCompileWdat (
1355 void **List)
1356 {
1357 ACPI_STATUS Status;
1358
1359
1360 Status = DtCompileTwoSubtables (List,
1361 AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
1362 return (Status);
1363 }
1364
1365
1366 /******************************************************************************
1367 *
1368 * FUNCTION: DtCompileXsdt
1369 *
1370 * PARAMETERS: List - Current field list pointer
1371 *
1372 * RETURN: Status
1373 *
1374 * DESCRIPTION: Compile XSDT.
1375 *
1376 *****************************************************************************/
1377
1378 ACPI_STATUS
1379 DtCompileXsdt (
1380 void **List)
1381 {
1382 DT_SUBTABLE *Subtable;
1383 DT_SUBTABLE *ParentTable;
1384 DT_FIELD *FieldList = *(DT_FIELD **) List;
1385 UINT64 Address;
1386
1387 ParentTable = DtPeekSubtable ();
1388
1389 while (FieldList)
1390 {
1391 DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
1392
1393 DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
1394 DtInsertSubtable (ParentTable, Subtable);
1395 FieldList = FieldList->Next;
1396 }
1397
1398 return (AE_OK);
1399 }
1400