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