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 <contrib/dev/acpica/compiler/aslcompiler.h> 121 #include <contrib/dev/acpica/compiler/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 *Rsdp; 268 ACPI_RSDP_EXTENSION *RsdpExtension; 269 ACPI_STATUS Status; 270 271 272 /* Compile the "common" RSDP (ACPI 1.0) */ 273 274 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp1, 275 &Gbl_RootTable, TRUE); 276 if (ACPI_FAILURE (Status)) 277 { 278 return (Status); 279 } 280 281 Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Gbl_RootTable->Buffer); 282 DtSetTableChecksum (&Rsdp->Checksum); 283 284 if (Rsdp->Revision > 0) 285 { 286 /* Compile the "extended" part of the RSDP as a subtable */ 287 288 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp2, 289 &Subtable, TRUE); 290 if (ACPI_FAILURE (Status)) 291 { 292 return (Status); 293 } 294 295 DtInsertSubtable (Gbl_RootTable, Subtable); 296 297 /* Set length and extended checksum for entire RSDP */ 298 299 RsdpExtension = ACPI_CAST_PTR (ACPI_RSDP_EXTENSION, Subtable->Buffer); 300 RsdpExtension->Length = Gbl_RootTable->Length + Subtable->Length; 301 DtSetTableChecksum (&RsdpExtension->ExtendedChecksum); 302 } 303 304 return (AE_OK); 305 } 306 307 308 /****************************************************************************** 309 * 310 * FUNCTION: DtCompileAsf 311 * 312 * PARAMETERS: List - Current field list pointer 313 * 314 * RETURN: Status 315 * 316 * DESCRIPTION: Compile ASF!. 317 * 318 *****************************************************************************/ 319 320 ACPI_STATUS 321 DtCompileAsf ( 322 void **List) 323 { 324 ACPI_ASF_INFO *AsfTable; 325 DT_SUBTABLE *Subtable; 326 DT_SUBTABLE *ParentTable; 327 ACPI_DMTABLE_INFO *InfoTable; 328 ACPI_DMTABLE_INFO *DataInfoTable = NULL; 329 UINT32 DataCount = 0; 330 ACPI_STATUS Status; 331 UINT32 i; 332 DT_FIELD **PFieldList = (DT_FIELD **) List; 333 DT_FIELD *SubtableStart; 334 335 336 while (*PFieldList) 337 { 338 SubtableStart = *PFieldList; 339 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr, 340 &Subtable, TRUE); 341 if (ACPI_FAILURE (Status)) 342 { 343 return (Status); 344 } 345 346 ParentTable = DtPeekSubtable (); 347 DtInsertSubtable (ParentTable, Subtable); 348 DtPushSubtable (Subtable); 349 350 AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer); 351 352 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */ 353 { 354 case ACPI_ASF_TYPE_INFO: 355 InfoTable = AcpiDmTableInfoAsf0; 356 break; 357 358 case ACPI_ASF_TYPE_ALERT: 359 InfoTable = AcpiDmTableInfoAsf1; 360 break; 361 362 case ACPI_ASF_TYPE_CONTROL: 363 InfoTable = AcpiDmTableInfoAsf2; 364 break; 365 366 case ACPI_ASF_TYPE_BOOT: 367 InfoTable = AcpiDmTableInfoAsf3; 368 break; 369 370 case ACPI_ASF_TYPE_ADDRESS: 371 InfoTable = AcpiDmTableInfoAsf4; 372 break; 373 374 default: 375 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); 376 return (AE_ERROR); 377 } 378 379 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 380 if (ACPI_FAILURE (Status)) 381 { 382 return (Status); 383 } 384 385 ParentTable = DtPeekSubtable (); 386 DtInsertSubtable (ParentTable, Subtable); 387 388 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */ 389 { 390 case ACPI_ASF_TYPE_INFO: 391 DataInfoTable = NULL; 392 break; 393 394 case ACPI_ASF_TYPE_ALERT: 395 DataInfoTable = AcpiDmTableInfoAsf1a; 396 DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT, 397 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 398 sizeof (ACPI_ASF_HEADER)))->Alerts; 399 break; 400 401 case ACPI_ASF_TYPE_CONTROL: 402 DataInfoTable = AcpiDmTableInfoAsf2a; 403 DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, 404 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 405 sizeof (ACPI_ASF_HEADER)))->Controls; 406 break; 407 408 case ACPI_ASF_TYPE_BOOT: 409 DataInfoTable = NULL; 410 break; 411 412 case ACPI_ASF_TYPE_ADDRESS: 413 DataInfoTable = TableInfoAsfAddress; 414 DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, 415 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 416 sizeof (ACPI_ASF_HEADER)))->Devices; 417 break; 418 419 default: 420 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); 421 return (AE_ERROR); 422 } 423 424 if (DataInfoTable) 425 { 426 switch (AsfTable->Header.Type & 0x7F) 427 { 428 case ACPI_ASF_TYPE_ADDRESS: 429 430 while (DataCount > 0) 431 { 432 Status = DtCompileTable (PFieldList, DataInfoTable, 433 &Subtable, TRUE); 434 if (ACPI_FAILURE (Status)) 435 { 436 return (Status); 437 } 438 439 DtInsertSubtable (ParentTable, Subtable); 440 DataCount = DataCount - Subtable->Length; 441 } 442 break; 443 444 default: 445 446 for (i = 0; i < DataCount; i++) 447 { 448 Status = DtCompileTable (PFieldList, DataInfoTable, 449 &Subtable, TRUE); 450 if (ACPI_FAILURE (Status)) 451 { 452 return (Status); 453 } 454 455 DtInsertSubtable (ParentTable, Subtable); 456 } 457 break; 458 } 459 } 460 461 DtPopSubtable (); 462 } 463 464 return (AE_OK); 465 } 466 467 468 /****************************************************************************** 469 * 470 * FUNCTION: DtCompileCpep 471 * 472 * PARAMETERS: List - Current field list pointer 473 * 474 * RETURN: Status 475 * 476 * DESCRIPTION: Compile CPEP. 477 * 478 *****************************************************************************/ 479 480 ACPI_STATUS 481 DtCompileCpep ( 482 void **List) 483 { 484 ACPI_STATUS Status; 485 486 487 Status = DtCompileTwoSubtables (List, 488 AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0); 489 return (Status); 490 } 491 492 493 /****************************************************************************** 494 * 495 * FUNCTION: DtCompileDmar 496 * 497 * PARAMETERS: List - Current field list pointer 498 * 499 * RETURN: Status 500 * 501 * DESCRIPTION: Compile DMAR. 502 * 503 *****************************************************************************/ 504 505 ACPI_STATUS 506 DtCompileDmar ( 507 void **List) 508 { 509 ACPI_STATUS Status; 510 DT_SUBTABLE *Subtable; 511 DT_SUBTABLE *ParentTable; 512 DT_FIELD **PFieldList = (DT_FIELD **) List; 513 DT_FIELD *SubtableStart; 514 ACPI_DMTABLE_INFO *InfoTable; 515 ACPI_DMAR_HEADER *DmarHeader; 516 UINT8 *ReservedBuffer; 517 UINT32 ReservedSize; 518 519 520 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable, TRUE); 521 if (ACPI_FAILURE (Status)) 522 { 523 return (Status); 524 } 525 526 ParentTable = DtPeekSubtable (); 527 DtInsertSubtable (ParentTable, Subtable); 528 529 /* DMAR Reserved area */ 530 531 ReservedSize = (UINT32) sizeof (((ACPI_TABLE_DMAR *) NULL)->Reserved); 532 ReservedBuffer = UtLocalCalloc (ReservedSize); 533 534 DtCreateSubtable (ReservedBuffer, ReservedSize, &Subtable); 535 536 ACPI_FREE (ReservedBuffer); 537 ParentTable = DtPeekSubtable (); 538 DtInsertSubtable (ParentTable, Subtable); 539 540 while (*PFieldList) 541 { 542 /* DMAR Header */ 543 544 SubtableStart = *PFieldList; 545 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr, 546 &Subtable, TRUE); 547 if (ACPI_FAILURE (Status)) 548 { 549 return (Status); 550 } 551 552 ParentTable = DtPeekSubtable (); 553 DtInsertSubtable (ParentTable, Subtable); 554 DtPushSubtable (Subtable); 555 556 DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer); 557 558 switch (DmarHeader->Type) 559 { 560 case ACPI_DMAR_TYPE_HARDWARE_UNIT: 561 InfoTable = AcpiDmTableInfoDmar0; 562 break; 563 case ACPI_DMAR_TYPE_RESERVED_MEMORY: 564 InfoTable = AcpiDmTableInfoDmar1; 565 break; 566 case ACPI_DMAR_TYPE_ATSR: 567 InfoTable = AcpiDmTableInfoDmar2; 568 break; 569 case ACPI_DMAR_HARDWARE_AFFINITY: 570 InfoTable = AcpiDmTableInfoDmar3; 571 break; 572 default: 573 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR"); 574 return (AE_ERROR); 575 } 576 577 /* DMAR Subtable */ 578 579 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 580 if (ACPI_FAILURE (Status)) 581 { 582 return (Status); 583 } 584 585 ParentTable = DtPeekSubtable (); 586 DtInsertSubtable (ParentTable, Subtable); 587 588 /* Optional Device Scope subtables */ 589 590 while (*PFieldList) 591 { 592 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope, 593 &Subtable, FALSE); 594 if (Status == AE_NOT_FOUND) 595 { 596 break; 597 } 598 599 ParentTable = DtPeekSubtable (); 600 DtInsertSubtable (ParentTable, Subtable); 601 DtPushSubtable (Subtable); 602 603 /* Optional PCI Paths */ 604 605 while (*PFieldList) 606 { 607 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath, 608 &Subtable, FALSE); 609 if (Status == AE_NOT_FOUND) 610 { 611 DtPopSubtable (); 612 break; 613 } 614 615 ParentTable = DtPeekSubtable (); 616 DtInsertSubtable (ParentTable, Subtable); 617 } 618 } 619 620 DtPopSubtable (); 621 } 622 623 return (AE_OK); 624 } 625 626 627 /****************************************************************************** 628 * 629 * FUNCTION: DtCompileEinj 630 * 631 * PARAMETERS: List - Current field list pointer 632 * 633 * RETURN: Status 634 * 635 * DESCRIPTION: Compile EINJ. 636 * 637 *****************************************************************************/ 638 639 ACPI_STATUS 640 DtCompileEinj ( 641 void **List) 642 { 643 ACPI_STATUS Status; 644 645 646 Status = DtCompileTwoSubtables (List, 647 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0); 648 return (Status); 649 } 650 651 652 /****************************************************************************** 653 * 654 * FUNCTION: DtCompileErst 655 * 656 * PARAMETERS: List - Current field list pointer 657 * 658 * RETURN: Status 659 * 660 * DESCRIPTION: Compile ERST. 661 * 662 *****************************************************************************/ 663 664 ACPI_STATUS 665 DtCompileErst ( 666 void **List) 667 { 668 ACPI_STATUS Status; 669 670 671 Status = DtCompileTwoSubtables (List, 672 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0); 673 return (Status); 674 } 675 676 677 /****************************************************************************** 678 * 679 * FUNCTION: DtCompileFadt 680 * 681 * PARAMETERS: List - Current field list pointer 682 * 683 * RETURN: Status 684 * 685 * DESCRIPTION: Compile FADT. 686 * 687 *****************************************************************************/ 688 689 ACPI_STATUS 690 DtCompileFadt ( 691 void **List) 692 { 693 ACPI_STATUS Status; 694 DT_SUBTABLE *Subtable; 695 DT_SUBTABLE *ParentTable; 696 DT_FIELD **PFieldList = (DT_FIELD **) List; 697 ACPI_TABLE_HEADER *Table; 698 UINT8 Revision; 699 700 701 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt1, 702 &Subtable, TRUE); 703 if (ACPI_FAILURE (Status)) 704 { 705 return (Status); 706 } 707 708 ParentTable = DtPeekSubtable (); 709 DtInsertSubtable (ParentTable, Subtable); 710 711 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 712 Revision = Table->Revision; 713 714 if (Revision == 2) 715 { 716 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt2, 717 &Subtable, TRUE); 718 if (ACPI_FAILURE (Status)) 719 { 720 return (Status); 721 } 722 723 DtInsertSubtable (ParentTable, Subtable); 724 } 725 else if (Revision >= 2) 726 { 727 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt3, 728 &Subtable, TRUE); 729 if (ACPI_FAILURE (Status)) 730 { 731 return (Status); 732 } 733 734 DtInsertSubtable (ParentTable, Subtable); 735 } 736 737 return (AE_OK); 738 } 739 740 741 /****************************************************************************** 742 * 743 * FUNCTION: DtCompileHest 744 * 745 * PARAMETERS: List - Current field list pointer 746 * 747 * RETURN: Status 748 * 749 * DESCRIPTION: Compile HEST. 750 * 751 *****************************************************************************/ 752 753 ACPI_STATUS 754 DtCompileHest ( 755 void **List) 756 { 757 ACPI_STATUS Status; 758 DT_SUBTABLE *Subtable; 759 DT_SUBTABLE *ParentTable; 760 DT_FIELD **PFieldList = (DT_FIELD **) List; 761 DT_FIELD *SubtableStart; 762 ACPI_DMTABLE_INFO *InfoTable; 763 UINT16 Type; 764 UINT32 BankCount; 765 766 767 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest, 768 &Subtable, TRUE); 769 if (ACPI_FAILURE (Status)) 770 { 771 return (Status); 772 } 773 774 ParentTable = DtPeekSubtable (); 775 DtInsertSubtable (ParentTable, Subtable); 776 777 while (*PFieldList) 778 { 779 /* Get subtable type */ 780 781 SubtableStart = *PFieldList; 782 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0); 783 784 switch (Type) 785 { 786 case ACPI_HEST_TYPE_IA32_CHECK: 787 InfoTable = AcpiDmTableInfoHest0; 788 break; 789 790 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 791 InfoTable = AcpiDmTableInfoHest1; 792 break; 793 794 case ACPI_HEST_TYPE_IA32_NMI: 795 InfoTable = AcpiDmTableInfoHest2; 796 break; 797 798 case ACPI_HEST_TYPE_AER_ROOT_PORT: 799 InfoTable = AcpiDmTableInfoHest6; 800 break; 801 802 case ACPI_HEST_TYPE_AER_ENDPOINT: 803 InfoTable = AcpiDmTableInfoHest7; 804 break; 805 806 case ACPI_HEST_TYPE_AER_BRIDGE: 807 InfoTable = AcpiDmTableInfoHest8; 808 break; 809 810 case ACPI_HEST_TYPE_GENERIC_ERROR: 811 InfoTable = AcpiDmTableInfoHest9; 812 break; 813 814 default: 815 /* Cannot continue on unknown type */ 816 817 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST"); 818 return (AE_ERROR); 819 } 820 821 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 822 if (ACPI_FAILURE (Status)) 823 { 824 return (Status); 825 } 826 827 DtInsertSubtable (ParentTable, Subtable); 828 829 /* 830 * Additional subtable data - IA32 Error Bank(s) 831 */ 832 BankCount = 0; 833 switch (Type) 834 { 835 case ACPI_HEST_TYPE_IA32_CHECK: 836 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK, 837 Subtable->Buffer))->NumHardwareBanks; 838 break; 839 840 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 841 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED, 842 Subtable->Buffer))->NumHardwareBanks; 843 break; 844 845 default: 846 break; 847 } 848 849 while (BankCount) 850 { 851 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank, 852 &Subtable, TRUE); 853 if (ACPI_FAILURE (Status)) 854 { 855 return (Status); 856 } 857 858 DtInsertSubtable (ParentTable, Subtable); 859 BankCount--; 860 } 861 } 862 863 return AE_OK; 864 } 865 866 867 /****************************************************************************** 868 * 869 * FUNCTION: DtCompileIvrs 870 * 871 * PARAMETERS: List - Current field list pointer 872 * 873 * RETURN: Status 874 * 875 * DESCRIPTION: Compile IVRS. 876 * 877 *****************************************************************************/ 878 879 ACPI_STATUS 880 DtCompileIvrs ( 881 void **List) 882 { 883 ACPI_STATUS Status; 884 DT_SUBTABLE *Subtable; 885 DT_SUBTABLE *ParentTable; 886 DT_FIELD **PFieldList = (DT_FIELD **) List; 887 DT_FIELD *SubtableStart; 888 ACPI_DMTABLE_INFO *InfoTable; 889 ACPI_IVRS_HEADER *IvrsHeader; 890 UINT8 EntryType; 891 892 893 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs, 894 &Subtable, TRUE); 895 if (ACPI_FAILURE (Status)) 896 { 897 return (Status); 898 } 899 900 ParentTable = DtPeekSubtable (); 901 DtInsertSubtable (ParentTable, Subtable); 902 903 while (*PFieldList) 904 { 905 SubtableStart = *PFieldList; 906 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr, 907 &Subtable, TRUE); 908 if (ACPI_FAILURE (Status)) 909 { 910 return (Status); 911 } 912 913 ParentTable = DtPeekSubtable (); 914 DtInsertSubtable (ParentTable, Subtable); 915 DtPushSubtable (Subtable); 916 917 IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer); 918 919 switch (IvrsHeader->Type) 920 { 921 case ACPI_IVRS_TYPE_HARDWARE: 922 InfoTable = AcpiDmTableInfoIvrs0; 923 break; 924 925 case ACPI_IVRS_TYPE_MEMORY1: 926 case ACPI_IVRS_TYPE_MEMORY2: 927 case ACPI_IVRS_TYPE_MEMORY3: 928 InfoTable = AcpiDmTableInfoIvrs1; 929 break; 930 931 default: 932 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS"); 933 return (AE_ERROR); 934 } 935 936 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 937 if (ACPI_FAILURE (Status)) 938 { 939 return (Status); 940 } 941 942 ParentTable = DtPeekSubtable (); 943 DtInsertSubtable (ParentTable, Subtable); 944 945 if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE) 946 { 947 while (*PFieldList && 948 !ACPI_STRCMP ((*PFieldList)->Name, "Entry Type")) 949 { 950 SubtableStart = *PFieldList; 951 DtCompileInteger (&EntryType, *PFieldList, 1, 0); 952 953 switch (EntryType) 954 { 955 /* 4-byte device entries */ 956 957 case ACPI_IVRS_TYPE_PAD4: 958 case ACPI_IVRS_TYPE_ALL: 959 case ACPI_IVRS_TYPE_SELECT: 960 case ACPI_IVRS_TYPE_START: 961 case ACPI_IVRS_TYPE_END: 962 963 InfoTable = AcpiDmTableInfoIvrs4; 964 break; 965 966 /* 8-byte entries, type A */ 967 968 case ACPI_IVRS_TYPE_ALIAS_SELECT: 969 case ACPI_IVRS_TYPE_ALIAS_START: 970 971 InfoTable = AcpiDmTableInfoIvrs8a; 972 break; 973 974 /* 8-byte entries, type B */ 975 976 case ACPI_IVRS_TYPE_PAD8: 977 case ACPI_IVRS_TYPE_EXT_SELECT: 978 case ACPI_IVRS_TYPE_EXT_START: 979 980 InfoTable = AcpiDmTableInfoIvrs8b; 981 break; 982 983 /* 8-byte entries, type C */ 984 985 case ACPI_IVRS_TYPE_SPECIAL: 986 987 InfoTable = AcpiDmTableInfoIvrs8c; 988 break; 989 990 default: 991 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, 992 "IVRS Device Entry"); 993 return (AE_ERROR); 994 } 995 996 Status = DtCompileTable (PFieldList, InfoTable, 997 &Subtable, TRUE); 998 if (ACPI_FAILURE (Status)) 999 { 1000 return (Status); 1001 } 1002 1003 DtInsertSubtable (ParentTable, Subtable); 1004 } 1005 } 1006 1007 DtPopSubtable (); 1008 } 1009 1010 return (AE_OK); 1011 } 1012 1013 1014 /****************************************************************************** 1015 * 1016 * FUNCTION: DtCompileMadt 1017 * 1018 * PARAMETERS: List - Current field list pointer 1019 * 1020 * RETURN: Status 1021 * 1022 * DESCRIPTION: Compile MADT. 1023 * 1024 *****************************************************************************/ 1025 1026 ACPI_STATUS 1027 DtCompileMadt ( 1028 void **List) 1029 { 1030 ACPI_STATUS Status; 1031 DT_SUBTABLE *Subtable; 1032 DT_SUBTABLE *ParentTable; 1033 DT_FIELD **PFieldList = (DT_FIELD **) List; 1034 DT_FIELD *SubtableStart; 1035 ACPI_SUBTABLE_HEADER *MadtHeader; 1036 ACPI_DMTABLE_INFO *InfoTable; 1037 1038 1039 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt, 1040 &Subtable, TRUE); 1041 if (ACPI_FAILURE (Status)) 1042 { 1043 return (Status); 1044 } 1045 1046 ParentTable = DtPeekSubtable (); 1047 DtInsertSubtable (ParentTable, Subtable); 1048 1049 while (*PFieldList) 1050 { 1051 SubtableStart = *PFieldList; 1052 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr, 1053 &Subtable, TRUE); 1054 if (ACPI_FAILURE (Status)) 1055 { 1056 return (Status); 1057 } 1058 1059 ParentTable = DtPeekSubtable (); 1060 DtInsertSubtable (ParentTable, Subtable); 1061 DtPushSubtable (Subtable); 1062 1063 MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1064 1065 switch (MadtHeader->Type) 1066 { 1067 case ACPI_MADT_TYPE_LOCAL_APIC: 1068 InfoTable = AcpiDmTableInfoMadt0; 1069 break; 1070 case ACPI_MADT_TYPE_IO_APIC: 1071 InfoTable = AcpiDmTableInfoMadt1; 1072 break; 1073 case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: 1074 InfoTable = AcpiDmTableInfoMadt2; 1075 break; 1076 case ACPI_MADT_TYPE_NMI_SOURCE: 1077 InfoTable = AcpiDmTableInfoMadt3; 1078 break; 1079 case ACPI_MADT_TYPE_LOCAL_APIC_NMI: 1080 InfoTable = AcpiDmTableInfoMadt4; 1081 break; 1082 case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: 1083 InfoTable = AcpiDmTableInfoMadt5; 1084 break; 1085 case ACPI_MADT_TYPE_IO_SAPIC: 1086 InfoTable = AcpiDmTableInfoMadt6; 1087 break; 1088 case ACPI_MADT_TYPE_LOCAL_SAPIC: 1089 InfoTable = AcpiDmTableInfoMadt7; 1090 break; 1091 case ACPI_MADT_TYPE_INTERRUPT_SOURCE: 1092 InfoTable = AcpiDmTableInfoMadt8; 1093 break; 1094 case ACPI_MADT_TYPE_LOCAL_X2APIC: 1095 InfoTable = AcpiDmTableInfoMadt9; 1096 break; 1097 case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI: 1098 InfoTable = AcpiDmTableInfoMadt10; 1099 break; 1100 default: 1101 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT"); 1102 return (AE_ERROR); 1103 } 1104 1105 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1106 if (ACPI_FAILURE (Status)) 1107 { 1108 return (Status); 1109 } 1110 1111 ParentTable = DtPeekSubtable (); 1112 DtInsertSubtable (ParentTable, Subtable); 1113 DtPopSubtable (); 1114 } 1115 1116 return (AE_OK); 1117 } 1118 1119 1120 /****************************************************************************** 1121 * 1122 * FUNCTION: DtCompileMcfg 1123 * 1124 * PARAMETERS: List - Current field list pointer 1125 * 1126 * RETURN: Status 1127 * 1128 * DESCRIPTION: Compile MCFG. 1129 * 1130 *****************************************************************************/ 1131 1132 ACPI_STATUS 1133 DtCompileMcfg ( 1134 void **List) 1135 { 1136 ACPI_STATUS Status; 1137 1138 1139 Status = DtCompileTwoSubtables (List, 1140 AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0); 1141 return (Status); 1142 } 1143 1144 1145 /****************************************************************************** 1146 * 1147 * FUNCTION: DtCompileMsct 1148 * 1149 * PARAMETERS: List - Current field list pointer 1150 * 1151 * RETURN: Status 1152 * 1153 * DESCRIPTION: Compile MSCT. 1154 * 1155 *****************************************************************************/ 1156 1157 ACPI_STATUS 1158 DtCompileMsct ( 1159 void **List) 1160 { 1161 ACPI_STATUS Status; 1162 1163 1164 Status = DtCompileTwoSubtables (List, 1165 AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0); 1166 return (Status); 1167 } 1168 1169 1170 /****************************************************************************** 1171 * 1172 * FUNCTION: DtCompileRsdt 1173 * 1174 * PARAMETERS: List - Current field list pointer 1175 * 1176 * RETURN: Status 1177 * 1178 * DESCRIPTION: Compile RSDT. 1179 * 1180 *****************************************************************************/ 1181 1182 ACPI_STATUS 1183 DtCompileRsdt ( 1184 void **List) 1185 { 1186 DT_SUBTABLE *Subtable; 1187 DT_SUBTABLE *ParentTable; 1188 DT_FIELD *FieldList = *(DT_FIELD **) List; 1189 UINT32 Address; 1190 1191 1192 ParentTable = DtPeekSubtable (); 1193 1194 while (FieldList) 1195 { 1196 DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO); 1197 1198 DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable); 1199 DtInsertSubtable (ParentTable, Subtable); 1200 FieldList = FieldList->Next; 1201 } 1202 1203 return (AE_OK); 1204 } 1205 1206 1207 /****************************************************************************** 1208 * 1209 * FUNCTION: DtCompileSlit 1210 * 1211 * PARAMETERS: List - Current field list pointer 1212 * 1213 * RETURN: Status 1214 * 1215 * DESCRIPTION: Compile SLIT. 1216 * 1217 *****************************************************************************/ 1218 1219 ACPI_STATUS 1220 DtCompileSlit ( 1221 void **List) 1222 { 1223 ACPI_STATUS Status; 1224 DT_SUBTABLE *Subtable; 1225 DT_SUBTABLE *ParentTable; 1226 DT_FIELD **PFieldList = (DT_FIELD **) List; 1227 DT_FIELD *FieldList; 1228 UINT32 Localities; 1229 UINT8 *LocalityBuffer; 1230 UINT32 RemainingData; 1231 1232 1233 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit, 1234 &Subtable, TRUE); 1235 if (ACPI_FAILURE (Status)) 1236 { 1237 return (Status); 1238 } 1239 1240 ParentTable = DtPeekSubtable (); 1241 DtInsertSubtable (ParentTable, Subtable); 1242 1243 Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer); 1244 LocalityBuffer = UtLocalCalloc (Localities); 1245 1246 FieldList = *PFieldList; 1247 while (FieldList) 1248 { 1249 /* Handle multiple-line buffer */ 1250 1251 RemainingData = Localities; 1252 while (RemainingData && FieldList) 1253 { 1254 RemainingData = DtCompileBuffer ( 1255 LocalityBuffer + (Localities - RemainingData), 1256 FieldList->Value, FieldList, RemainingData); 1257 FieldList = FieldList->Next; 1258 } 1259 1260 DtCreateSubtable (LocalityBuffer, Localities, &Subtable); 1261 DtInsertSubtable (ParentTable, Subtable); 1262 } 1263 1264 ACPI_FREE (LocalityBuffer); 1265 return (AE_OK); 1266 } 1267 1268 1269 /****************************************************************************** 1270 * 1271 * FUNCTION: DtCompileSrat 1272 * 1273 * PARAMETERS: List - Current field list pointer 1274 * 1275 * RETURN: Status 1276 * 1277 * DESCRIPTION: Compile SRAT. 1278 * 1279 *****************************************************************************/ 1280 1281 ACPI_STATUS 1282 DtCompileSrat ( 1283 void **List) 1284 { 1285 ACPI_STATUS Status; 1286 DT_SUBTABLE *Subtable; 1287 DT_SUBTABLE *ParentTable; 1288 DT_FIELD **PFieldList = (DT_FIELD **) List; 1289 DT_FIELD *SubtableStart; 1290 ACPI_SUBTABLE_HEADER *SratHeader; 1291 ACPI_DMTABLE_INFO *InfoTable; 1292 1293 1294 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat, 1295 &Subtable, TRUE); 1296 if (ACPI_FAILURE (Status)) 1297 { 1298 return (Status); 1299 } 1300 1301 ParentTable = DtPeekSubtable (); 1302 DtInsertSubtable (ParentTable, Subtable); 1303 1304 while (*PFieldList) 1305 { 1306 SubtableStart = *PFieldList; 1307 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr, 1308 &Subtable, TRUE); 1309 if (ACPI_FAILURE (Status)) 1310 { 1311 return (Status); 1312 } 1313 1314 ParentTable = DtPeekSubtable (); 1315 DtInsertSubtable (ParentTable, Subtable); 1316 DtPushSubtable (Subtable); 1317 1318 SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1319 1320 switch (SratHeader->Type) 1321 { 1322 case ACPI_SRAT_TYPE_CPU_AFFINITY: 1323 InfoTable = AcpiDmTableInfoSrat0; 1324 break; 1325 case ACPI_SRAT_TYPE_MEMORY_AFFINITY: 1326 InfoTable = AcpiDmTableInfoSrat1; 1327 break; 1328 case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: 1329 InfoTable = AcpiDmTableInfoSrat2; 1330 break; 1331 default: 1332 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT"); 1333 return (AE_ERROR); 1334 } 1335 1336 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1337 if (ACPI_FAILURE (Status)) 1338 { 1339 return (Status); 1340 } 1341 1342 ParentTable = DtPeekSubtable (); 1343 DtInsertSubtable (ParentTable, Subtable); 1344 DtPopSubtable (); 1345 } 1346 1347 return (AE_OK); 1348 } 1349 1350 1351 /****************************************************************************** 1352 * 1353 * FUNCTION: DtCompileWdat 1354 * 1355 * PARAMETERS: List - Current field list pointer 1356 * 1357 * RETURN: Status 1358 * 1359 * DESCRIPTION: Compile WDAT. 1360 * 1361 *****************************************************************************/ 1362 1363 ACPI_STATUS 1364 DtCompileWdat ( 1365 void **List) 1366 { 1367 ACPI_STATUS Status; 1368 1369 1370 Status = DtCompileTwoSubtables (List, 1371 AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0); 1372 return (Status); 1373 } 1374 1375 1376 /****************************************************************************** 1377 * 1378 * FUNCTION: DtCompileXsdt 1379 * 1380 * PARAMETERS: List - Current field list pointer 1381 * 1382 * RETURN: Status 1383 * 1384 * DESCRIPTION: Compile XSDT. 1385 * 1386 *****************************************************************************/ 1387 1388 ACPI_STATUS 1389 DtCompileXsdt ( 1390 void **List) 1391 { 1392 DT_SUBTABLE *Subtable; 1393 DT_SUBTABLE *ParentTable; 1394 DT_FIELD *FieldList = *(DT_FIELD **) List; 1395 UINT64 Address; 1396 1397 ParentTable = DtPeekSubtable (); 1398 1399 while (FieldList) 1400 { 1401 DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO); 1402 1403 DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable); 1404 DtInsertSubtable (ParentTable, Subtable); 1405 FieldList = FieldList->Next; 1406 } 1407 1408 return (AE_OK); 1409 } 1410