dttable.c revision 245582
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 57static ACPI_DMTABLE_INFO TableInfoAsfAddress[] = 58{ 59 {ACPI_DMT_BUFFER, 0, "Addresses", 0}, 60 {ACPI_DMT_EXIT, 0, NULL, 0} 61}; 62 63static 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 78static ACPI_STATUS 79DtCompileTwoSubtables ( 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 100static ACPI_STATUS 101DtCompileTwoSubtables ( 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 148ACPI_STATUS 149DtCompileFacs ( 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 190ACPI_STATUS 191DtCompileRsdp ( 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 248ACPI_STATUS 249DtCompileAsf ( 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 408ACPI_STATUS 409DtCompileCpep ( 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 433ACPI_STATUS 434DtCompileCsrt ( 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 521ACPI_STATUS 522DtCompileDmar ( 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 655ACPI_STATUS 656DtCompileEinj ( 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 680ACPI_STATUS 681DtCompileErst ( 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 705ACPI_STATUS 706DtCompileFadt ( 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 781ACPI_STATUS 782DtCompileFpdt ( 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 853ACPI_STATUS 854DtCompileHest ( 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 979ACPI_STATUS 980DtCompileIvrs ( 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 1126ACPI_STATUS 1127DtCompileMadt ( 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 1238ACPI_STATUS 1239DtCompileMcfg ( 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 1263ACPI_STATUS 1264DtCompileMpst ( 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 1400ACPI_STATUS 1401DtCompileMsct ( 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: DtCompilePmtt 1416 * 1417 * PARAMETERS: List - Current field list pointer 1418 * 1419 * RETURN: Status 1420 * 1421 * DESCRIPTION: Compile PMTT. 1422 * 1423 *****************************************************************************/ 1424 1425ACPI_STATUS 1426DtCompilePmtt ( 1427 void **List) 1428{ 1429 ACPI_STATUS Status; 1430 DT_SUBTABLE *Subtable; 1431 DT_SUBTABLE *ParentTable; 1432 DT_FIELD **PFieldList = (DT_FIELD **) List; 1433 DT_FIELD *SubtableStart; 1434 ACPI_PMTT_HEADER *PmttHeader; 1435 ACPI_PMTT_CONTROLLER *PmttController; 1436 UINT16 DomainCount; 1437 UINT8 PrevType = ACPI_PMTT_TYPE_SOCKET; 1438 1439 1440 /* Main table */ 1441 1442 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable, TRUE); 1443 if (ACPI_FAILURE (Status)) 1444 { 1445 return (Status); 1446 } 1447 1448 ParentTable = DtPeekSubtable (); 1449 DtInsertSubtable (ParentTable, Subtable); 1450 DtPushSubtable (Subtable); 1451 1452 while (*PFieldList) 1453 { 1454 SubtableStart = *PFieldList; 1455 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttHdr, 1456 &Subtable, TRUE); 1457 if (ACPI_FAILURE (Status)) 1458 { 1459 return (Status); 1460 } 1461 1462 PmttHeader = ACPI_CAST_PTR (ACPI_PMTT_HEADER, Subtable->Buffer); 1463 while (PrevType >= PmttHeader->Type) 1464 { 1465 DtPopSubtable (); 1466 1467 if (PrevType == ACPI_PMTT_TYPE_SOCKET) 1468 { 1469 break; 1470 } 1471 PrevType--; 1472 } 1473 PrevType = PmttHeader->Type; 1474 1475 ParentTable = DtPeekSubtable (); 1476 DtInsertSubtable (ParentTable, Subtable); 1477 DtPushSubtable (Subtable); 1478 1479 switch (PmttHeader->Type) 1480 { 1481 case ACPI_PMTT_TYPE_SOCKET: 1482 1483 /* Subtable: Socket Structure */ 1484 1485 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0, 1486 &Subtable, TRUE); 1487 if (ACPI_FAILURE (Status)) 1488 { 1489 return (Status); 1490 } 1491 1492 ParentTable = DtPeekSubtable (); 1493 DtInsertSubtable (ParentTable, Subtable); 1494 break; 1495 1496 case ACPI_PMTT_TYPE_CONTROLLER: 1497 1498 /* Subtable: Memory Controller Structure */ 1499 1500 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1, 1501 &Subtable, TRUE); 1502 if (ACPI_FAILURE (Status)) 1503 { 1504 return (Status); 1505 } 1506 1507 ParentTable = DtPeekSubtable (); 1508 DtInsertSubtable (ParentTable, Subtable); 1509 1510 PmttController = ACPI_CAST_PTR (ACPI_PMTT_CONTROLLER, 1511 (Subtable->Buffer - sizeof (ACPI_PMTT_HEADER))); 1512 DomainCount = PmttController->DomainCount; 1513 1514 while (DomainCount) 1515 { 1516 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1a, 1517 &Subtable, TRUE); 1518 if (ACPI_FAILURE (Status)) 1519 { 1520 return (Status); 1521 } 1522 1523 DtInsertSubtable (ParentTable, Subtable); 1524 DomainCount--; 1525 } 1526 break; 1527 1528 case ACPI_PMTT_TYPE_DIMM: 1529 1530 /* Subtable: Physical Component Structure */ 1531 1532 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2, 1533 &Subtable, TRUE); 1534 if (ACPI_FAILURE (Status)) 1535 { 1536 return (Status); 1537 } 1538 1539 ParentTable = DtPeekSubtable (); 1540 DtInsertSubtable (ParentTable, Subtable); 1541 break; 1542 1543 default: 1544 1545 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT"); 1546 return (AE_ERROR); 1547 } 1548 } 1549 1550 return (Status); 1551} 1552 1553 1554/****************************************************************************** 1555 * 1556 * FUNCTION: DtCompileRsdt 1557 * 1558 * PARAMETERS: List - Current field list pointer 1559 * 1560 * RETURN: Status 1561 * 1562 * DESCRIPTION: Compile RSDT. 1563 * 1564 *****************************************************************************/ 1565 1566ACPI_STATUS 1567DtCompileRsdt ( 1568 void **List) 1569{ 1570 DT_SUBTABLE *Subtable; 1571 DT_SUBTABLE *ParentTable; 1572 DT_FIELD *FieldList = *(DT_FIELD **) List; 1573 UINT32 Address; 1574 1575 1576 ParentTable = DtPeekSubtable (); 1577 1578 while (FieldList) 1579 { 1580 DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO); 1581 1582 DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable); 1583 DtInsertSubtable (ParentTable, Subtable); 1584 FieldList = FieldList->Next; 1585 } 1586 1587 return (AE_OK); 1588} 1589 1590 1591/****************************************************************************** 1592 * 1593 * FUNCTION: DtCompileS3pt 1594 * 1595 * PARAMETERS: PFieldList - Current field list pointer 1596 * 1597 * RETURN: Status 1598 * 1599 * DESCRIPTION: Compile S3PT (Pointed to by FPDT) 1600 * 1601 *****************************************************************************/ 1602 1603ACPI_STATUS 1604DtCompileS3pt ( 1605 DT_FIELD **PFieldList) 1606{ 1607 ACPI_STATUS Status; 1608 ACPI_S3PT_HEADER *S3ptHeader; 1609 DT_SUBTABLE *Subtable; 1610 DT_SUBTABLE *ParentTable; 1611 ACPI_DMTABLE_INFO *InfoTable; 1612 DT_FIELD *SubtableStart; 1613 1614 1615 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt, 1616 &Gbl_RootTable, TRUE); 1617 if (ACPI_FAILURE (Status)) 1618 { 1619 return (Status); 1620 } 1621 1622 DtPushSubtable (Gbl_RootTable); 1623 1624 while (*PFieldList) 1625 { 1626 SubtableStart = *PFieldList; 1627 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr, 1628 &Subtable, TRUE); 1629 if (ACPI_FAILURE (Status)) 1630 { 1631 return (Status); 1632 } 1633 1634 ParentTable = DtPeekSubtable (); 1635 DtInsertSubtable (ParentTable, Subtable); 1636 DtPushSubtable (Subtable); 1637 1638 S3ptHeader = ACPI_CAST_PTR (ACPI_S3PT_HEADER, Subtable->Buffer); 1639 1640 switch (S3ptHeader->Type) 1641 { 1642 case ACPI_S3PT_TYPE_RESUME: 1643 InfoTable = AcpiDmTableInfoS3pt0; 1644 break; 1645 1646 case ACPI_S3PT_TYPE_SUSPEND: 1647 InfoTable = AcpiDmTableInfoS3pt1; 1648 break; 1649 1650 default: 1651 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT"); 1652 return (AE_ERROR); 1653 } 1654 1655 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1656 if (ACPI_FAILURE (Status)) 1657 { 1658 return (Status); 1659 } 1660 1661 ParentTable = DtPeekSubtable (); 1662 DtInsertSubtable (ParentTable, Subtable); 1663 DtPopSubtable (); 1664 } 1665 1666 return (AE_OK); 1667} 1668 1669 1670/****************************************************************************** 1671 * 1672 * FUNCTION: DtCompileSlic 1673 * 1674 * PARAMETERS: List - Current field list pointer 1675 * 1676 * RETURN: Status 1677 * 1678 * DESCRIPTION: Compile SLIC. 1679 * 1680 *****************************************************************************/ 1681 1682ACPI_STATUS 1683DtCompileSlic ( 1684 void **List) 1685{ 1686 ACPI_STATUS Status; 1687 DT_SUBTABLE *Subtable; 1688 DT_SUBTABLE *ParentTable; 1689 DT_FIELD **PFieldList = (DT_FIELD **) List; 1690 DT_FIELD *SubtableStart; 1691 ACPI_SLIC_HEADER *SlicHeader; 1692 ACPI_DMTABLE_INFO *InfoTable; 1693 1694 1695 while (*PFieldList) 1696 { 1697 SubtableStart = *PFieldList; 1698 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlicHdr, 1699 &Subtable, TRUE); 1700 if (ACPI_FAILURE (Status)) 1701 { 1702 return (Status); 1703 } 1704 1705 ParentTable = DtPeekSubtable (); 1706 DtInsertSubtable (ParentTable, Subtable); 1707 DtPushSubtable (Subtable); 1708 1709 SlicHeader = ACPI_CAST_PTR (ACPI_SLIC_HEADER, Subtable->Buffer); 1710 1711 switch (SlicHeader->Type) 1712 { 1713 case ACPI_SLIC_TYPE_PUBLIC_KEY: 1714 InfoTable = AcpiDmTableInfoSlic0; 1715 break; 1716 case ACPI_SLIC_TYPE_WINDOWS_MARKER: 1717 InfoTable = AcpiDmTableInfoSlic1; 1718 break; 1719 default: 1720 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SLIC"); 1721 return (AE_ERROR); 1722 } 1723 1724 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1725 if (ACPI_FAILURE (Status)) 1726 { 1727 return (Status); 1728 } 1729 1730 ParentTable = DtPeekSubtable (); 1731 DtInsertSubtable (ParentTable, Subtable); 1732 DtPopSubtable (); 1733 } 1734 1735 return (AE_OK); 1736} 1737 1738 1739/****************************************************************************** 1740 * 1741 * FUNCTION: DtCompileSlit 1742 * 1743 * PARAMETERS: List - Current field list pointer 1744 * 1745 * RETURN: Status 1746 * 1747 * DESCRIPTION: Compile SLIT. 1748 * 1749 *****************************************************************************/ 1750 1751ACPI_STATUS 1752DtCompileSlit ( 1753 void **List) 1754{ 1755 ACPI_STATUS Status; 1756 DT_SUBTABLE *Subtable; 1757 DT_SUBTABLE *ParentTable; 1758 DT_FIELD **PFieldList = (DT_FIELD **) List; 1759 DT_FIELD *FieldList; 1760 UINT32 Localities; 1761 UINT8 *LocalityBuffer; 1762 1763 1764 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit, 1765 &Subtable, TRUE); 1766 if (ACPI_FAILURE (Status)) 1767 { 1768 return (Status); 1769 } 1770 1771 ParentTable = DtPeekSubtable (); 1772 DtInsertSubtable (ParentTable, Subtable); 1773 1774 Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer); 1775 LocalityBuffer = UtLocalCalloc (Localities); 1776 1777 /* Compile each locality buffer */ 1778 1779 FieldList = *PFieldList; 1780 while (FieldList) 1781 { 1782 DtCompileBuffer (LocalityBuffer, 1783 FieldList->Value, FieldList, Localities); 1784 1785 DtCreateSubtable (LocalityBuffer, Localities, &Subtable); 1786 DtInsertSubtable (ParentTable, Subtable); 1787 FieldList = FieldList->Next; 1788 } 1789 1790 ACPI_FREE (LocalityBuffer); 1791 return (AE_OK); 1792} 1793 1794 1795/****************************************************************************** 1796 * 1797 * FUNCTION: DtCompileSrat 1798 * 1799 * PARAMETERS: List - Current field list pointer 1800 * 1801 * RETURN: Status 1802 * 1803 * DESCRIPTION: Compile SRAT. 1804 * 1805 *****************************************************************************/ 1806 1807ACPI_STATUS 1808DtCompileSrat ( 1809 void **List) 1810{ 1811 ACPI_STATUS Status; 1812 DT_SUBTABLE *Subtable; 1813 DT_SUBTABLE *ParentTable; 1814 DT_FIELD **PFieldList = (DT_FIELD **) List; 1815 DT_FIELD *SubtableStart; 1816 ACPI_SUBTABLE_HEADER *SratHeader; 1817 ACPI_DMTABLE_INFO *InfoTable; 1818 1819 1820 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat, 1821 &Subtable, TRUE); 1822 if (ACPI_FAILURE (Status)) 1823 { 1824 return (Status); 1825 } 1826 1827 ParentTable = DtPeekSubtable (); 1828 DtInsertSubtable (ParentTable, Subtable); 1829 1830 while (*PFieldList) 1831 { 1832 SubtableStart = *PFieldList; 1833 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr, 1834 &Subtable, TRUE); 1835 if (ACPI_FAILURE (Status)) 1836 { 1837 return (Status); 1838 } 1839 1840 ParentTable = DtPeekSubtable (); 1841 DtInsertSubtable (ParentTable, Subtable); 1842 DtPushSubtable (Subtable); 1843 1844 SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1845 1846 switch (SratHeader->Type) 1847 { 1848 case ACPI_SRAT_TYPE_CPU_AFFINITY: 1849 InfoTable = AcpiDmTableInfoSrat0; 1850 break; 1851 case ACPI_SRAT_TYPE_MEMORY_AFFINITY: 1852 InfoTable = AcpiDmTableInfoSrat1; 1853 break; 1854 case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: 1855 InfoTable = AcpiDmTableInfoSrat2; 1856 break; 1857 default: 1858 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT"); 1859 return (AE_ERROR); 1860 } 1861 1862 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1863 if (ACPI_FAILURE (Status)) 1864 { 1865 return (Status); 1866 } 1867 1868 ParentTable = DtPeekSubtable (); 1869 DtInsertSubtable (ParentTable, Subtable); 1870 DtPopSubtable (); 1871 } 1872 1873 return (AE_OK); 1874} 1875 1876 1877/****************************************************************************** 1878 * 1879 * FUNCTION: DtGetGenericTableInfo 1880 * 1881 * PARAMETERS: Name - Generic type name 1882 * 1883 * RETURN: Info entry 1884 * 1885 * DESCRIPTION: Obtain table info for a generic name entry 1886 * 1887 *****************************************************************************/ 1888 1889ACPI_DMTABLE_INFO * 1890DtGetGenericTableInfo ( 1891 char *Name) 1892{ 1893 ACPI_DMTABLE_INFO *Info; 1894 UINT32 i; 1895 1896 1897 if (!Name) 1898 { 1899 return (NULL); 1900 } 1901 1902 /* Search info table for name match */ 1903 1904 for (i = 0; ; i++) 1905 { 1906 Info = AcpiDmTableInfoGeneric[i]; 1907 if (Info->Opcode == ACPI_DMT_EXIT) 1908 { 1909 Info = NULL; 1910 break; 1911 } 1912 1913 /* Use caseless compare for generic keywords */ 1914 1915 if (!AcpiUtStricmp (Name, Info->Name)) 1916 { 1917 break; 1918 } 1919 } 1920 1921 return (Info); 1922} 1923 1924 1925/****************************************************************************** 1926 * 1927 * FUNCTION: DtCompileUefi 1928 * 1929 * PARAMETERS: List - Current field list pointer 1930 * 1931 * RETURN: Status 1932 * 1933 * DESCRIPTION: Compile UEFI. 1934 * 1935 *****************************************************************************/ 1936 1937ACPI_STATUS 1938DtCompileUefi ( 1939 void **List) 1940{ 1941 ACPI_STATUS Status; 1942 DT_SUBTABLE *Subtable; 1943 DT_SUBTABLE *ParentTable; 1944 DT_FIELD **PFieldList = (DT_FIELD **) List; 1945 UINT16 *DataOffset; 1946 1947 1948 /* Compile the predefined portion of the UEFI table */ 1949 1950 Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi, 1951 &Subtable, TRUE); 1952 if (ACPI_FAILURE (Status)) 1953 { 1954 return (Status); 1955 } 1956 1957 DataOffset = (UINT16 *) (Subtable->Buffer + 16); 1958 *DataOffset = sizeof (ACPI_TABLE_UEFI); 1959 1960 ParentTable = DtPeekSubtable (); 1961 DtInsertSubtable (ParentTable, Subtable); 1962 1963 /* 1964 * Compile the "generic" portion of the UEFI table. This 1965 * part of the table is not predefined and any of the generic 1966 * operators may be used. 1967 */ 1968 1969 DtCompileGeneric ((void **) PFieldList); 1970 1971 return (AE_OK); 1972} 1973 1974 1975/****************************************************************************** 1976 * 1977 * FUNCTION: DtCompileWdat 1978 * 1979 * PARAMETERS: List - Current field list pointer 1980 * 1981 * RETURN: Status 1982 * 1983 * DESCRIPTION: Compile WDAT. 1984 * 1985 *****************************************************************************/ 1986 1987ACPI_STATUS 1988DtCompileWdat ( 1989 void **List) 1990{ 1991 ACPI_STATUS Status; 1992 1993 1994 Status = DtCompileTwoSubtables (List, 1995 AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0); 1996 return (Status); 1997} 1998 1999 2000/****************************************************************************** 2001 * 2002 * FUNCTION: DtCompileXsdt 2003 * 2004 * PARAMETERS: List - Current field list pointer 2005 * 2006 * RETURN: Status 2007 * 2008 * DESCRIPTION: Compile XSDT. 2009 * 2010 *****************************************************************************/ 2011 2012ACPI_STATUS 2013DtCompileXsdt ( 2014 void **List) 2015{ 2016 DT_SUBTABLE *Subtable; 2017 DT_SUBTABLE *ParentTable; 2018 DT_FIELD *FieldList = *(DT_FIELD **) List; 2019 UINT64 Address; 2020 2021 ParentTable = DtPeekSubtable (); 2022 2023 while (FieldList) 2024 { 2025 DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO); 2026 2027 DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable); 2028 DtInsertSubtable (ParentTable, Subtable); 2029 FieldList = FieldList->Next; 2030 } 2031 2032 return (AE_OK); 2033} 2034 2035 2036/****************************************************************************** 2037 * 2038 * FUNCTION: DtCompileGeneric 2039 * 2040 * PARAMETERS: List - Current field list pointer 2041 * 2042 * RETURN: Status 2043 * 2044 * DESCRIPTION: Compile generic unknown table. 2045 * 2046 *****************************************************************************/ 2047 2048ACPI_STATUS 2049DtCompileGeneric ( 2050 void **List) 2051{ 2052 ACPI_STATUS Status; 2053 DT_SUBTABLE *Subtable; 2054 DT_SUBTABLE *ParentTable; 2055 DT_FIELD **PFieldList = (DT_FIELD **) List; 2056 ACPI_DMTABLE_INFO *Info; 2057 2058 2059 ParentTable = DtPeekSubtable (); 2060 2061 /* 2062 * Compile the "generic" portion of the table. This 2063 * part of the table is not predefined and any of the generic 2064 * operators may be used. 2065 */ 2066 2067 /* Find any and all labels in the entire generic portion */ 2068 2069 DtDetectAllLabels (*PFieldList); 2070 2071 /* Now we can actually compile the parse tree */ 2072 2073 while (*PFieldList) 2074 { 2075 Info = DtGetGenericTableInfo ((*PFieldList)->Name); 2076 if (!Info) 2077 { 2078 sprintf (MsgBuffer, "Generic data type \"%s\" not found", 2079 (*PFieldList)->Name); 2080 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 2081 (*PFieldList), MsgBuffer); 2082 2083 *PFieldList = (*PFieldList)->Next; 2084 continue; 2085 } 2086 2087 Status = DtCompileTable (PFieldList, Info, 2088 &Subtable, TRUE); 2089 if (ACPI_SUCCESS (Status)) 2090 { 2091 DtInsertSubtable (ParentTable, Subtable); 2092 } 2093 else 2094 { 2095 *PFieldList = (*PFieldList)->Next; 2096 2097 if (Status == AE_NOT_FOUND) 2098 { 2099 sprintf (MsgBuffer, "Generic data type \"%s\" not found", 2100 (*PFieldList)->Name); 2101 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 2102 (*PFieldList), MsgBuffer); 2103 } 2104 } 2105 } 2106 2107 return (AE_OK); 2108} 2109