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