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