1 /****************************************************************************** 2 * 3 * Module Name: dttable.c - handling for specific ACPI tables 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2014, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #define __DTTABLE_C__ 45 46 /* Compile all complex data tables */ 47 48 #include <contrib/dev/acpica/compiler/aslcompiler.h> 49 #include <contrib/dev/acpica/compiler/dtcompiler.h> 50 51 #define _COMPONENT DT_COMPILER 52 ACPI_MODULE_NAME ("dttable") 53 54 55 /* TBD: merge these into dmtbinfo.c? */ 56 57 static ACPI_DMTABLE_INFO TableInfoAsfAddress[] = 58 { 59 {ACPI_DMT_BUFFER, 0, "Addresses", 0}, 60 {ACPI_DMT_EXIT, 0, NULL, 0} 61 }; 62 63 static ACPI_DMTABLE_INFO TableInfoDmarPciPath[] = 64 { 65 {ACPI_DMT_PCI_PATH, 0, "PCI Path", 0}, 66 {ACPI_DMT_EXIT, 0, NULL, 0} 67 }; 68 69 70 /* TBD: move to acmacros.h */ 71 72 #define ACPI_SUB_PTR(t, a, b) \ 73 ACPI_CAST_PTR (t, (ACPI_CAST_PTR (UINT8, (a)) - (ACPI_SIZE)(b))) 74 75 76 /* Local prototypes */ 77 78 static ACPI_STATUS 79 DtCompileTwoSubtables ( 80 void **List, 81 ACPI_DMTABLE_INFO *TableInfo1, 82 ACPI_DMTABLE_INFO *TableInfo2); 83 84 85 /****************************************************************************** 86 * 87 * FUNCTION: DtCompileTwoSubtables 88 * 89 * PARAMETERS: List - Current field list pointer 90 * TableInfo1 - Info table 1 91 * TableInfo1 - Info table 2 92 * 93 * RETURN: Status 94 * 95 * DESCRIPTION: Compile tables with a header and one or more same subtables. 96 * Include CPEP, EINJ, ERST, MCFG, MSCT, WDAT 97 * 98 *****************************************************************************/ 99 100 static ACPI_STATUS 101 DtCompileTwoSubtables ( 102 void **List, 103 ACPI_DMTABLE_INFO *TableInfo1, 104 ACPI_DMTABLE_INFO *TableInfo2) 105 { 106 ACPI_STATUS Status; 107 DT_SUBTABLE *Subtable; 108 DT_SUBTABLE *ParentTable; 109 DT_FIELD **PFieldList = (DT_FIELD **) List; 110 111 112 Status = DtCompileTable (PFieldList, TableInfo1, &Subtable, TRUE); 113 if (ACPI_FAILURE (Status)) 114 { 115 return (Status); 116 } 117 118 ParentTable = DtPeekSubtable (); 119 DtInsertSubtable (ParentTable, Subtable); 120 121 while (*PFieldList) 122 { 123 Status = DtCompileTable (PFieldList, TableInfo2, &Subtable, FALSE); 124 if (ACPI_FAILURE (Status)) 125 { 126 return (Status); 127 } 128 129 DtInsertSubtable (ParentTable, Subtable); 130 } 131 132 return (AE_OK); 133 } 134 135 136 /****************************************************************************** 137 * 138 * FUNCTION: DtCompileFacs 139 * 140 * PARAMETERS: PFieldList - Current field list pointer 141 * 142 * RETURN: Status 143 * 144 * DESCRIPTION: Compile FACS. 145 * 146 *****************************************************************************/ 147 148 ACPI_STATUS 149 DtCompileFacs ( 150 DT_FIELD **PFieldList) 151 { 152 DT_SUBTABLE *Subtable; 153 UINT8 *ReservedBuffer; 154 ACPI_STATUS Status; 155 UINT32 ReservedSize; 156 157 158 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFacs, 159 &Gbl_RootTable, TRUE); 160 if (ACPI_FAILURE (Status)) 161 { 162 return (Status); 163 } 164 165 /* Large FACS reserved area at the end of the table */ 166 167 ReservedSize = (UINT32) sizeof (((ACPI_TABLE_FACS *) NULL)->Reserved1); 168 ReservedBuffer = UtLocalCalloc (ReservedSize); 169 170 DtCreateSubtable (ReservedBuffer, ReservedSize, &Subtable); 171 172 ACPI_FREE (ReservedBuffer); 173 DtInsertSubtable (Gbl_RootTable, Subtable); 174 return (AE_OK); 175 } 176 177 178 /****************************************************************************** 179 * 180 * FUNCTION: DtCompileRsdp 181 * 182 * PARAMETERS: PFieldList - Current field list pointer 183 * 184 * RETURN: Status 185 * 186 * DESCRIPTION: Compile RSDP. 187 * 188 *****************************************************************************/ 189 190 ACPI_STATUS 191 DtCompileRsdp ( 192 DT_FIELD **PFieldList) 193 { 194 DT_SUBTABLE *Subtable; 195 ACPI_TABLE_RSDP *Rsdp; 196 ACPI_RSDP_EXTENSION *RsdpExtension; 197 ACPI_STATUS Status; 198 199 200 /* Compile the "common" RSDP (ACPI 1.0) */ 201 202 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp1, 203 &Gbl_RootTable, TRUE); 204 if (ACPI_FAILURE (Status)) 205 { 206 return (Status); 207 } 208 209 Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Gbl_RootTable->Buffer); 210 DtSetTableChecksum (&Rsdp->Checksum); 211 212 if (Rsdp->Revision > 0) 213 { 214 /* Compile the "extended" part of the RSDP as a subtable */ 215 216 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp2, 217 &Subtable, TRUE); 218 if (ACPI_FAILURE (Status)) 219 { 220 return (Status); 221 } 222 223 DtInsertSubtable (Gbl_RootTable, Subtable); 224 225 /* Set length and extended checksum for entire RSDP */ 226 227 RsdpExtension = ACPI_CAST_PTR (ACPI_RSDP_EXTENSION, Subtable->Buffer); 228 RsdpExtension->Length = Gbl_RootTable->Length + Subtable->Length; 229 DtSetTableChecksum (&RsdpExtension->ExtendedChecksum); 230 } 231 232 return (AE_OK); 233 } 234 235 236 /****************************************************************************** 237 * 238 * FUNCTION: DtCompileAsf 239 * 240 * PARAMETERS: List - Current field list pointer 241 * 242 * RETURN: Status 243 * 244 * DESCRIPTION: Compile ASF!. 245 * 246 *****************************************************************************/ 247 248 ACPI_STATUS 249 DtCompileAsf ( 250 void **List) 251 { 252 ACPI_ASF_INFO *AsfTable; 253 DT_SUBTABLE *Subtable; 254 DT_SUBTABLE *ParentTable; 255 ACPI_DMTABLE_INFO *InfoTable; 256 ACPI_DMTABLE_INFO *DataInfoTable = NULL; 257 UINT32 DataCount = 0; 258 ACPI_STATUS Status; 259 UINT32 i; 260 DT_FIELD **PFieldList = (DT_FIELD **) List; 261 DT_FIELD *SubtableStart; 262 263 264 while (*PFieldList) 265 { 266 SubtableStart = *PFieldList; 267 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr, 268 &Subtable, TRUE); 269 if (ACPI_FAILURE (Status)) 270 { 271 return (Status); 272 } 273 274 ParentTable = DtPeekSubtable (); 275 DtInsertSubtable (ParentTable, Subtable); 276 DtPushSubtable (Subtable); 277 278 AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer); 279 280 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */ 281 { 282 case ACPI_ASF_TYPE_INFO: 283 284 InfoTable = AcpiDmTableInfoAsf0; 285 break; 286 287 case ACPI_ASF_TYPE_ALERT: 288 289 InfoTable = AcpiDmTableInfoAsf1; 290 break; 291 292 case ACPI_ASF_TYPE_CONTROL: 293 294 InfoTable = AcpiDmTableInfoAsf2; 295 break; 296 297 case ACPI_ASF_TYPE_BOOT: 298 299 InfoTable = AcpiDmTableInfoAsf3; 300 break; 301 302 case ACPI_ASF_TYPE_ADDRESS: 303 304 InfoTable = AcpiDmTableInfoAsf4; 305 break; 306 307 default: 308 309 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); 310 return (AE_ERROR); 311 } 312 313 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 314 if (ACPI_FAILURE (Status)) 315 { 316 return (Status); 317 } 318 319 ParentTable = DtPeekSubtable (); 320 DtInsertSubtable (ParentTable, Subtable); 321 322 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */ 323 { 324 case ACPI_ASF_TYPE_INFO: 325 326 DataInfoTable = NULL; 327 break; 328 329 case ACPI_ASF_TYPE_ALERT: 330 331 DataInfoTable = AcpiDmTableInfoAsf1a; 332 DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT, 333 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 334 sizeof (ACPI_ASF_HEADER)))->Alerts; 335 break; 336 337 case ACPI_ASF_TYPE_CONTROL: 338 339 DataInfoTable = AcpiDmTableInfoAsf2a; 340 DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, 341 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 342 sizeof (ACPI_ASF_HEADER)))->Controls; 343 break; 344 345 case ACPI_ASF_TYPE_BOOT: 346 347 DataInfoTable = NULL; 348 break; 349 350 case ACPI_ASF_TYPE_ADDRESS: 351 352 DataInfoTable = TableInfoAsfAddress; 353 DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, 354 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 355 sizeof (ACPI_ASF_HEADER)))->Devices; 356 break; 357 358 default: 359 360 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); 361 return (AE_ERROR); 362 } 363 364 if (DataInfoTable) 365 { 366 switch (AsfTable->Header.Type & 0x7F) 367 { 368 case ACPI_ASF_TYPE_ADDRESS: 369 370 while (DataCount > 0) 371 { 372 Status = DtCompileTable (PFieldList, DataInfoTable, 373 &Subtable, TRUE); 374 if (ACPI_FAILURE (Status)) 375 { 376 return (Status); 377 } 378 379 DtInsertSubtable (ParentTable, Subtable); 380 DataCount = DataCount - Subtable->Length; 381 } 382 break; 383 384 default: 385 386 for (i = 0; i < DataCount; i++) 387 { 388 Status = DtCompileTable (PFieldList, DataInfoTable, 389 &Subtable, TRUE); 390 if (ACPI_FAILURE (Status)) 391 { 392 return (Status); 393 } 394 395 DtInsertSubtable (ParentTable, Subtable); 396 } 397 break; 398 } 399 } 400 401 DtPopSubtable (); 402 } 403 404 return (AE_OK); 405 } 406 407 408 /****************************************************************************** 409 * 410 * FUNCTION: DtCompileCpep 411 * 412 * PARAMETERS: List - Current field list pointer 413 * 414 * RETURN: Status 415 * 416 * DESCRIPTION: Compile CPEP. 417 * 418 *****************************************************************************/ 419 420 ACPI_STATUS 421 DtCompileCpep ( 422 void **List) 423 { 424 ACPI_STATUS Status; 425 426 427 Status = DtCompileTwoSubtables (List, 428 AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0); 429 return (Status); 430 } 431 432 433 /****************************************************************************** 434 * 435 * FUNCTION: DtCompileCsrt 436 * 437 * PARAMETERS: List - Current field list pointer 438 * 439 * RETURN: Status 440 * 441 * DESCRIPTION: Compile CSRT. 442 * 443 *****************************************************************************/ 444 445 ACPI_STATUS 446 DtCompileCsrt ( 447 void **List) 448 { 449 ACPI_STATUS Status = AE_OK; 450 DT_SUBTABLE *Subtable; 451 DT_SUBTABLE *ParentTable; 452 DT_FIELD **PFieldList = (DT_FIELD **) List; 453 UINT32 DescriptorCount; 454 UINT32 GroupLength; 455 456 457 /* Subtables (Resource Groups) */ 458 459 while (*PFieldList) 460 { 461 /* Resource group subtable */ 462 463 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0, 464 &Subtable, TRUE); 465 if (ACPI_FAILURE (Status)) 466 { 467 return (Status); 468 } 469 470 /* Compute the number of resource descriptors */ 471 472 GroupLength = 473 (ACPI_CAST_PTR (ACPI_CSRT_GROUP, 474 Subtable->Buffer))->Length - 475 (ACPI_CAST_PTR (ACPI_CSRT_GROUP, 476 Subtable->Buffer))->SharedInfoLength - 477 sizeof (ACPI_CSRT_GROUP); 478 479 DescriptorCount = (GroupLength / 480 sizeof (ACPI_CSRT_DESCRIPTOR)); 481 482 ParentTable = DtPeekSubtable (); 483 DtInsertSubtable (ParentTable, Subtable); 484 DtPushSubtable (Subtable); 485 486 /* Shared info subtable (One per resource group) */ 487 488 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1, 489 &Subtable, TRUE); 490 if (ACPI_FAILURE (Status)) 491 { 492 return (Status); 493 } 494 495 ParentTable = DtPeekSubtable (); 496 DtInsertSubtable (ParentTable, Subtable); 497 498 /* Sub-Subtables (Resource Descriptors) */ 499 500 while (*PFieldList && DescriptorCount) 501 { 502 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2, 503 &Subtable, TRUE); 504 if (ACPI_FAILURE (Status)) 505 { 506 return (Status); 507 } 508 509 ParentTable = DtPeekSubtable (); 510 DtInsertSubtable (ParentTable, Subtable); 511 DescriptorCount--; 512 } 513 514 DtPopSubtable (); 515 } 516 517 return (Status); 518 } 519 520 521 /****************************************************************************** 522 * 523 * FUNCTION: DtCompileDbg2 524 * 525 * PARAMETERS: List - Current field list pointer 526 * 527 * RETURN: Status 528 * 529 * DESCRIPTION: Compile DBG2. 530 * 531 *****************************************************************************/ 532 533 ACPI_STATUS 534 DtCompileDbg2 ( 535 void **List) 536 { 537 ACPI_STATUS Status; 538 DT_SUBTABLE *Subtable; 539 DT_SUBTABLE *ParentTable; 540 DT_FIELD **PFieldList = (DT_FIELD **) List; 541 UINT32 SubtableCount; 542 ACPI_DBG2_HEADER *Dbg2Header; 543 ACPI_DBG2_DEVICE *DeviceInfo; 544 UINT16 CurrentOffset; 545 UINT32 i; 546 547 548 /* Main table */ 549 550 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable, TRUE); 551 if (ACPI_FAILURE (Status)) 552 { 553 return (Status); 554 } 555 556 ParentTable = DtPeekSubtable (); 557 DtInsertSubtable (ParentTable, Subtable); 558 559 /* Main table fields */ 560 561 Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer); 562 Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF ( 563 ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header); 564 565 SubtableCount = Dbg2Header->InfoCount; 566 DtPushSubtable (Subtable); 567 568 /* Process all Device Information subtables (Count = InfoCount) */ 569 570 while (*PFieldList && SubtableCount) 571 { 572 /* Subtable: Debug Device Information */ 573 574 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device, 575 &Subtable, TRUE); 576 if (ACPI_FAILURE (Status)) 577 { 578 return (Status); 579 } 580 581 DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer); 582 CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE); 583 584 ParentTable = DtPeekSubtable (); 585 DtInsertSubtable (ParentTable, Subtable); 586 DtPushSubtable (Subtable); 587 588 ParentTable = DtPeekSubtable (); 589 590 /* BaseAddressRegister GAS array (Required, size is RegisterCount) */ 591 592 DeviceInfo->BaseAddressOffset = CurrentOffset; 593 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++) 594 { 595 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr, 596 &Subtable, TRUE); 597 if (ACPI_FAILURE (Status)) 598 { 599 return (Status); 600 } 601 602 CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS); 603 DtInsertSubtable (ParentTable, Subtable); 604 } 605 606 /* AddressSize array (Required, size = RegisterCount) */ 607 608 DeviceInfo->AddressSizeOffset = CurrentOffset; 609 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++) 610 { 611 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size, 612 &Subtable, TRUE); 613 if (ACPI_FAILURE (Status)) 614 { 615 return (Status); 616 } 617 618 CurrentOffset += (UINT16) sizeof (UINT32); 619 DtInsertSubtable (ParentTable, Subtable); 620 } 621 622 /* NamespaceString device identifier (Required, size = NamePathLength) */ 623 624 DeviceInfo->NamepathOffset = CurrentOffset; 625 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name, 626 &Subtable, TRUE); 627 if (ACPI_FAILURE (Status)) 628 { 629 return (Status); 630 } 631 632 /* Update the device info header */ 633 634 DeviceInfo->NamepathLength = (UINT16) Subtable->Length; 635 CurrentOffset += (UINT16) DeviceInfo->NamepathLength; 636 DtInsertSubtable (ParentTable, Subtable); 637 638 /* OemData - Variable-length data (Optional, size = OemDataLength) */ 639 640 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData, 641 &Subtable, TRUE); 642 if (ACPI_FAILURE (Status)) 643 { 644 return (Status); 645 } 646 647 /* Update the device info header (zeros if no OEM data present) */ 648 649 DeviceInfo->OemDataOffset = 0; 650 DeviceInfo->OemDataLength = 0; 651 652 /* Optional subtable (OemData) */ 653 654 if (Subtable && Subtable->Length) 655 { 656 DeviceInfo->OemDataOffset = CurrentOffset; 657 DeviceInfo->OemDataLength = (UINT16) Subtable->Length; 658 659 DtInsertSubtable (ParentTable, Subtable); 660 } 661 662 SubtableCount--; 663 DtPopSubtable (); /* Get next Device Information subtable */ 664 } 665 666 DtPopSubtable (); 667 return (AE_OK); 668 } 669 670 671 /****************************************************************************** 672 * 673 * FUNCTION: DtCompileDmar 674 * 675 * PARAMETERS: List - Current field list pointer 676 * 677 * RETURN: Status 678 * 679 * DESCRIPTION: Compile DMAR. 680 * 681 *****************************************************************************/ 682 683 ACPI_STATUS 684 DtCompileDmar ( 685 void **List) 686 { 687 ACPI_STATUS Status; 688 DT_SUBTABLE *Subtable; 689 DT_SUBTABLE *ParentTable; 690 DT_FIELD **PFieldList = (DT_FIELD **) List; 691 DT_FIELD *SubtableStart; 692 ACPI_DMTABLE_INFO *InfoTable; 693 ACPI_DMAR_HEADER *DmarHeader; 694 ACPI_DMAR_DEVICE_SCOPE *DmarDeviceScope; 695 UINT32 DeviceScopeLength; 696 UINT32 PciPathLength; 697 698 699 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable, TRUE); 700 if (ACPI_FAILURE (Status)) 701 { 702 return (Status); 703 } 704 705 ParentTable = DtPeekSubtable (); 706 DtInsertSubtable (ParentTable, Subtable); 707 DtPushSubtable (Subtable); 708 709 while (*PFieldList) 710 { 711 /* DMAR Header */ 712 713 SubtableStart = *PFieldList; 714 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr, 715 &Subtable, TRUE); 716 if (ACPI_FAILURE (Status)) 717 { 718 return (Status); 719 } 720 721 ParentTable = DtPeekSubtable (); 722 DtInsertSubtable (ParentTable, Subtable); 723 DtPushSubtable (Subtable); 724 725 DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer); 726 727 switch (DmarHeader->Type) 728 { 729 case ACPI_DMAR_TYPE_HARDWARE_UNIT: 730 731 InfoTable = AcpiDmTableInfoDmar0; 732 break; 733 734 case ACPI_DMAR_TYPE_RESERVED_MEMORY: 735 736 InfoTable = AcpiDmTableInfoDmar1; 737 break; 738 739 case ACPI_DMAR_TYPE_ROOT_ATS: 740 741 InfoTable = AcpiDmTableInfoDmar2; 742 break; 743 744 case ACPI_DMAR_TYPE_HARDWARE_AFFINITY: 745 746 InfoTable = AcpiDmTableInfoDmar3; 747 break; 748 749 case ACPI_DMAR_TYPE_NAMESPACE: 750 751 InfoTable = AcpiDmTableInfoDmar4; 752 break; 753 754 default: 755 756 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR"); 757 return (AE_ERROR); 758 } 759 760 /* DMAR Subtable */ 761 762 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 763 if (ACPI_FAILURE (Status)) 764 { 765 return (Status); 766 } 767 768 ParentTable = DtPeekSubtable (); 769 DtInsertSubtable (ParentTable, Subtable); 770 771 /* 772 * Optional Device Scope subtables 773 */ 774 if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) || 775 (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE)) 776 { 777 /* These types do not support device scopes */ 778 779 DtPopSubtable (); 780 continue; 781 } 782 783 DtPushSubtable (Subtable); 784 DeviceScopeLength = DmarHeader->Length - Subtable->Length - 785 ParentTable->Length; 786 while (DeviceScopeLength) 787 { 788 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope, 789 &Subtable, FALSE); 790 if (Status == AE_NOT_FOUND) 791 { 792 break; 793 } 794 795 ParentTable = DtPeekSubtable (); 796 DtInsertSubtable (ParentTable, Subtable); 797 DtPushSubtable (Subtable); 798 799 DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer); 800 801 /* Optional PCI Paths */ 802 803 PciPathLength = DmarDeviceScope->Length - Subtable->Length; 804 while (PciPathLength) 805 { 806 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath, 807 &Subtable, FALSE); 808 if (Status == AE_NOT_FOUND) 809 { 810 DtPopSubtable (); 811 break; 812 } 813 814 ParentTable = DtPeekSubtable (); 815 DtInsertSubtable (ParentTable, Subtable); 816 PciPathLength -= Subtable->Length; 817 } 818 819 DtPopSubtable (); 820 DeviceScopeLength -= DmarDeviceScope->Length; 821 } 822 823 DtPopSubtable (); 824 DtPopSubtable (); 825 } 826 827 return (AE_OK); 828 } 829 830 831 /****************************************************************************** 832 * 833 * FUNCTION: DtCompileEinj 834 * 835 * PARAMETERS: List - Current field list pointer 836 * 837 * RETURN: Status 838 * 839 * DESCRIPTION: Compile EINJ. 840 * 841 *****************************************************************************/ 842 843 ACPI_STATUS 844 DtCompileEinj ( 845 void **List) 846 { 847 ACPI_STATUS Status; 848 849 850 Status = DtCompileTwoSubtables (List, 851 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0); 852 return (Status); 853 } 854 855 856 /****************************************************************************** 857 * 858 * FUNCTION: DtCompileErst 859 * 860 * PARAMETERS: List - Current field list pointer 861 * 862 * RETURN: Status 863 * 864 * DESCRIPTION: Compile ERST. 865 * 866 *****************************************************************************/ 867 868 ACPI_STATUS 869 DtCompileErst ( 870 void **List) 871 { 872 ACPI_STATUS Status; 873 874 875 Status = DtCompileTwoSubtables (List, 876 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0); 877 return (Status); 878 } 879 880 881 /****************************************************************************** 882 * 883 * FUNCTION: DtCompileFadt 884 * 885 * PARAMETERS: List - Current field list pointer 886 * 887 * RETURN: Status 888 * 889 * DESCRIPTION: Compile FADT. 890 * 891 *****************************************************************************/ 892 893 ACPI_STATUS 894 DtCompileFadt ( 895 void **List) 896 { 897 ACPI_STATUS Status; 898 DT_SUBTABLE *Subtable; 899 DT_SUBTABLE *ParentTable; 900 DT_FIELD **PFieldList = (DT_FIELD **) List; 901 ACPI_TABLE_HEADER *Table; 902 UINT8 Revision; 903 904 905 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt1, 906 &Subtable, TRUE); 907 if (ACPI_FAILURE (Status)) 908 { 909 return (Status); 910 } 911 912 ParentTable = DtPeekSubtable (); 913 DtInsertSubtable (ParentTable, Subtable); 914 915 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 916 Revision = Table->Revision; 917 918 if (Revision == 2) 919 { 920 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt2, 921 &Subtable, TRUE); 922 if (ACPI_FAILURE (Status)) 923 { 924 return (Status); 925 } 926 927 DtInsertSubtable (ParentTable, Subtable); 928 } 929 else if (Revision >= 2) 930 { 931 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt3, 932 &Subtable, TRUE); 933 if (ACPI_FAILURE (Status)) 934 { 935 return (Status); 936 } 937 938 DtInsertSubtable (ParentTable, Subtable); 939 940 if (Revision >= 5) 941 { 942 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt5, 943 &Subtable, TRUE); 944 if (ACPI_FAILURE (Status)) 945 { 946 return (Status); 947 } 948 949 DtInsertSubtable (ParentTable, Subtable); 950 } 951 } 952 953 return (AE_OK); 954 } 955 956 /****************************************************************************** 957 * 958 * FUNCTION: DtCompileGtdt 959 * 960 * PARAMETERS: List - Current field list pointer 961 * 962 * RETURN: Status 963 * 964 * DESCRIPTION: Compile GTDT. 965 * 966 *****************************************************************************/ 967 968 ACPI_STATUS 969 DtCompileGtdt ( 970 void **List) 971 { 972 ACPI_STATUS Status; 973 DT_SUBTABLE *Subtable; 974 DT_SUBTABLE *ParentTable; 975 DT_FIELD **PFieldList = (DT_FIELD **) List; 976 DT_FIELD *SubtableStart; 977 ACPI_SUBTABLE_HEADER *GtdtHeader; 978 ACPI_DMTABLE_INFO *InfoTable; 979 UINT32 GtCount; 980 981 982 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt, 983 &Subtable, TRUE); 984 if (ACPI_FAILURE (Status)) 985 { 986 return (Status); 987 } 988 989 ParentTable = DtPeekSubtable (); 990 DtInsertSubtable (ParentTable, Subtable); 991 992 while (*PFieldList) 993 { 994 SubtableStart = *PFieldList; 995 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr, 996 &Subtable, TRUE); 997 if (ACPI_FAILURE (Status)) 998 { 999 return (Status); 1000 } 1001 1002 ParentTable = DtPeekSubtable (); 1003 DtInsertSubtable (ParentTable, Subtable); 1004 DtPushSubtable (Subtable); 1005 1006 GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1007 1008 switch (GtdtHeader->Type) 1009 { 1010 case ACPI_GTDT_TYPE_TIMER_BLOCK: 1011 1012 InfoTable = AcpiDmTableInfoGtdt0; 1013 break; 1014 1015 case ACPI_GTDT_TYPE_WATCHDOG: 1016 1017 InfoTable = AcpiDmTableInfoGtdt1; 1018 break; 1019 1020 default: 1021 1022 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT"); 1023 return (AE_ERROR); 1024 } 1025 1026 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1027 if (ACPI_FAILURE (Status)) 1028 { 1029 return (Status); 1030 } 1031 1032 ParentTable = DtPeekSubtable (); 1033 DtInsertSubtable (ParentTable, Subtable); 1034 1035 /* 1036 * Additional GT block subtable data 1037 */ 1038 1039 switch (GtdtHeader->Type) 1040 { 1041 case ACPI_GTDT_TYPE_TIMER_BLOCK: 1042 1043 DtPushSubtable (Subtable); 1044 ParentTable = DtPeekSubtable (); 1045 1046 GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK, 1047 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount; 1048 while (GtCount) 1049 { 1050 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a, 1051 &Subtable, TRUE); 1052 if (ACPI_FAILURE (Status)) 1053 { 1054 return (Status); 1055 } 1056 1057 1058 DtInsertSubtable (ParentTable, Subtable); 1059 GtCount--; 1060 } 1061 DtPopSubtable (); 1062 break; 1063 1064 default: 1065 1066 break; 1067 } 1068 1069 DtPopSubtable (); 1070 } 1071 1072 return (AE_OK); 1073 } 1074 1075 1076 /****************************************************************************** 1077 * 1078 * FUNCTION: DtCompileFpdt 1079 * 1080 * PARAMETERS: List - Current field list pointer 1081 * 1082 * RETURN: Status 1083 * 1084 * DESCRIPTION: Compile FPDT. 1085 * 1086 *****************************************************************************/ 1087 1088 ACPI_STATUS 1089 DtCompileFpdt ( 1090 void **List) 1091 { 1092 ACPI_STATUS Status; 1093 ACPI_FPDT_HEADER *FpdtHeader; 1094 DT_SUBTABLE *Subtable; 1095 DT_SUBTABLE *ParentTable; 1096 ACPI_DMTABLE_INFO *InfoTable; 1097 DT_FIELD **PFieldList = (DT_FIELD **) List; 1098 DT_FIELD *SubtableStart; 1099 1100 1101 while (*PFieldList) 1102 { 1103 SubtableStart = *PFieldList; 1104 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr, 1105 &Subtable, TRUE); 1106 if (ACPI_FAILURE (Status)) 1107 { 1108 return (Status); 1109 } 1110 1111 ParentTable = DtPeekSubtable (); 1112 DtInsertSubtable (ParentTable, Subtable); 1113 DtPushSubtable (Subtable); 1114 1115 FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer); 1116 1117 switch (FpdtHeader->Type) 1118 { 1119 case ACPI_FPDT_TYPE_BOOT: 1120 1121 InfoTable = AcpiDmTableInfoFpdt0; 1122 break; 1123 1124 case ACPI_FPDT_TYPE_S3PERF: 1125 1126 InfoTable = AcpiDmTableInfoFpdt1; 1127 break; 1128 1129 default: 1130 1131 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT"); 1132 return (AE_ERROR); 1133 break; 1134 } 1135 1136 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1137 if (ACPI_FAILURE (Status)) 1138 { 1139 return (Status); 1140 } 1141 1142 ParentTable = DtPeekSubtable (); 1143 DtInsertSubtable (ParentTable, Subtable); 1144 DtPopSubtable (); 1145 } 1146 1147 return (AE_OK); 1148 } 1149 1150 1151 /****************************************************************************** 1152 * 1153 * FUNCTION: DtCompileHest 1154 * 1155 * PARAMETERS: List - Current field list pointer 1156 * 1157 * RETURN: Status 1158 * 1159 * DESCRIPTION: Compile HEST. 1160 * 1161 *****************************************************************************/ 1162 1163 ACPI_STATUS 1164 DtCompileHest ( 1165 void **List) 1166 { 1167 ACPI_STATUS Status; 1168 DT_SUBTABLE *Subtable; 1169 DT_SUBTABLE *ParentTable; 1170 DT_FIELD **PFieldList = (DT_FIELD **) List; 1171 DT_FIELD *SubtableStart; 1172 ACPI_DMTABLE_INFO *InfoTable; 1173 UINT16 Type; 1174 UINT32 BankCount; 1175 1176 1177 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest, 1178 &Subtable, TRUE); 1179 if (ACPI_FAILURE (Status)) 1180 { 1181 return (Status); 1182 } 1183 1184 ParentTable = DtPeekSubtable (); 1185 DtInsertSubtable (ParentTable, Subtable); 1186 1187 while (*PFieldList) 1188 { 1189 /* Get subtable type */ 1190 1191 SubtableStart = *PFieldList; 1192 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0); 1193 1194 switch (Type) 1195 { 1196 case ACPI_HEST_TYPE_IA32_CHECK: 1197 1198 InfoTable = AcpiDmTableInfoHest0; 1199 break; 1200 1201 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 1202 1203 InfoTable = AcpiDmTableInfoHest1; 1204 break; 1205 1206 case ACPI_HEST_TYPE_IA32_NMI: 1207 1208 InfoTable = AcpiDmTableInfoHest2; 1209 break; 1210 1211 case ACPI_HEST_TYPE_AER_ROOT_PORT: 1212 1213 InfoTable = AcpiDmTableInfoHest6; 1214 break; 1215 1216 case ACPI_HEST_TYPE_AER_ENDPOINT: 1217 1218 InfoTable = AcpiDmTableInfoHest7; 1219 break; 1220 1221 case ACPI_HEST_TYPE_AER_BRIDGE: 1222 1223 InfoTable = AcpiDmTableInfoHest8; 1224 break; 1225 1226 case ACPI_HEST_TYPE_GENERIC_ERROR: 1227 1228 InfoTable = AcpiDmTableInfoHest9; 1229 break; 1230 1231 default: 1232 1233 /* Cannot continue on unknown type */ 1234 1235 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST"); 1236 return (AE_ERROR); 1237 } 1238 1239 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1240 if (ACPI_FAILURE (Status)) 1241 { 1242 return (Status); 1243 } 1244 1245 DtInsertSubtable (ParentTable, Subtable); 1246 1247 /* 1248 * Additional subtable data - IA32 Error Bank(s) 1249 */ 1250 BankCount = 0; 1251 switch (Type) 1252 { 1253 case ACPI_HEST_TYPE_IA32_CHECK: 1254 1255 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK, 1256 Subtable->Buffer))->NumHardwareBanks; 1257 break; 1258 1259 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 1260 1261 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED, 1262 Subtable->Buffer))->NumHardwareBanks; 1263 break; 1264 1265 default: 1266 1267 break; 1268 } 1269 1270 while (BankCount) 1271 { 1272 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank, 1273 &Subtable, TRUE); 1274 if (ACPI_FAILURE (Status)) 1275 { 1276 return (Status); 1277 } 1278 1279 DtInsertSubtable (ParentTable, Subtable); 1280 BankCount--; 1281 } 1282 } 1283 1284 return (AE_OK); 1285 } 1286 1287 1288 /****************************************************************************** 1289 * 1290 * FUNCTION: DtCompileIvrs 1291 * 1292 * PARAMETERS: List - Current field list pointer 1293 * 1294 * RETURN: Status 1295 * 1296 * DESCRIPTION: Compile IVRS. 1297 * 1298 *****************************************************************************/ 1299 1300 ACPI_STATUS 1301 DtCompileIvrs ( 1302 void **List) 1303 { 1304 ACPI_STATUS Status; 1305 DT_SUBTABLE *Subtable; 1306 DT_SUBTABLE *ParentTable; 1307 DT_FIELD **PFieldList = (DT_FIELD **) List; 1308 DT_FIELD *SubtableStart; 1309 ACPI_DMTABLE_INFO *InfoTable; 1310 ACPI_IVRS_HEADER *IvrsHeader; 1311 UINT8 EntryType; 1312 1313 1314 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs, 1315 &Subtable, TRUE); 1316 if (ACPI_FAILURE (Status)) 1317 { 1318 return (Status); 1319 } 1320 1321 ParentTable = DtPeekSubtable (); 1322 DtInsertSubtable (ParentTable, Subtable); 1323 1324 while (*PFieldList) 1325 { 1326 SubtableStart = *PFieldList; 1327 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr, 1328 &Subtable, TRUE); 1329 if (ACPI_FAILURE (Status)) 1330 { 1331 return (Status); 1332 } 1333 1334 ParentTable = DtPeekSubtable (); 1335 DtInsertSubtable (ParentTable, Subtable); 1336 DtPushSubtable (Subtable); 1337 1338 IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer); 1339 1340 switch (IvrsHeader->Type) 1341 { 1342 case ACPI_IVRS_TYPE_HARDWARE: 1343 1344 InfoTable = AcpiDmTableInfoIvrs0; 1345 break; 1346 1347 case ACPI_IVRS_TYPE_MEMORY1: 1348 case ACPI_IVRS_TYPE_MEMORY2: 1349 case ACPI_IVRS_TYPE_MEMORY3: 1350 1351 InfoTable = AcpiDmTableInfoIvrs1; 1352 break; 1353 1354 default: 1355 1356 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS"); 1357 return (AE_ERROR); 1358 } 1359 1360 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1361 if (ACPI_FAILURE (Status)) 1362 { 1363 return (Status); 1364 } 1365 1366 ParentTable = DtPeekSubtable (); 1367 DtInsertSubtable (ParentTable, Subtable); 1368 1369 if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE) 1370 { 1371 while (*PFieldList && 1372 !ACPI_STRCMP ((*PFieldList)->Name, "Entry Type")) 1373 { 1374 SubtableStart = *PFieldList; 1375 DtCompileInteger (&EntryType, *PFieldList, 1, 0); 1376 1377 switch (EntryType) 1378 { 1379 /* 4-byte device entries */ 1380 1381 case ACPI_IVRS_TYPE_PAD4: 1382 case ACPI_IVRS_TYPE_ALL: 1383 case ACPI_IVRS_TYPE_SELECT: 1384 case ACPI_IVRS_TYPE_START: 1385 case ACPI_IVRS_TYPE_END: 1386 1387 InfoTable = AcpiDmTableInfoIvrs4; 1388 break; 1389 1390 /* 8-byte entries, type A */ 1391 1392 case ACPI_IVRS_TYPE_ALIAS_SELECT: 1393 case ACPI_IVRS_TYPE_ALIAS_START: 1394 1395 InfoTable = AcpiDmTableInfoIvrs8a; 1396 break; 1397 1398 /* 8-byte entries, type B */ 1399 1400 case ACPI_IVRS_TYPE_PAD8: 1401 case ACPI_IVRS_TYPE_EXT_SELECT: 1402 case ACPI_IVRS_TYPE_EXT_START: 1403 1404 InfoTable = AcpiDmTableInfoIvrs8b; 1405 break; 1406 1407 /* 8-byte entries, type C */ 1408 1409 case ACPI_IVRS_TYPE_SPECIAL: 1410 1411 InfoTable = AcpiDmTableInfoIvrs8c; 1412 break; 1413 1414 default: 1415 1416 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, 1417 "IVRS Device Entry"); 1418 return (AE_ERROR); 1419 } 1420 1421 Status = DtCompileTable (PFieldList, InfoTable, 1422 &Subtable, TRUE); 1423 if (ACPI_FAILURE (Status)) 1424 { 1425 return (Status); 1426 } 1427 1428 DtInsertSubtable (ParentTable, Subtable); 1429 } 1430 } 1431 1432 DtPopSubtable (); 1433 } 1434 1435 return (AE_OK); 1436 } 1437 1438 1439 /****************************************************************************** 1440 * 1441 * FUNCTION: DtCompileLpit 1442 * 1443 * PARAMETERS: List - Current field list pointer 1444 * 1445 * RETURN: Status 1446 * 1447 * DESCRIPTION: Compile LPIT. 1448 * 1449 *****************************************************************************/ 1450 1451 ACPI_STATUS 1452 DtCompileLpit ( 1453 void **List) 1454 { 1455 ACPI_STATUS Status; 1456 DT_SUBTABLE *Subtable; 1457 DT_SUBTABLE *ParentTable; 1458 DT_FIELD **PFieldList = (DT_FIELD **) List; 1459 DT_FIELD *SubtableStart; 1460 ACPI_DMTABLE_INFO *InfoTable; 1461 ACPI_LPIT_HEADER *LpitHeader; 1462 1463 1464 /* Note: Main table consists only of the standard ACPI table header */ 1465 1466 while (*PFieldList) 1467 { 1468 SubtableStart = *PFieldList; 1469 1470 /* LPIT Subtable header */ 1471 1472 Status = DtCompileTable (PFieldList, AcpiDmTableInfoLpitHdr, 1473 &Subtable, TRUE); 1474 if (ACPI_FAILURE (Status)) 1475 { 1476 return (Status); 1477 } 1478 1479 ParentTable = DtPeekSubtable (); 1480 DtInsertSubtable (ParentTable, Subtable); 1481 DtPushSubtable (Subtable); 1482 1483 LpitHeader = ACPI_CAST_PTR (ACPI_LPIT_HEADER, Subtable->Buffer); 1484 1485 switch (LpitHeader->Type) 1486 { 1487 case ACPI_LPIT_TYPE_NATIVE_CSTATE: 1488 1489 InfoTable = AcpiDmTableInfoLpit0; 1490 break; 1491 1492 case ACPI_LPIT_TYPE_SIMPLE_IO: 1493 1494 InfoTable = AcpiDmTableInfoLpit1; 1495 break; 1496 1497 default: 1498 1499 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "LPIT"); 1500 return (AE_ERROR); 1501 } 1502 1503 /* LPIT Subtable */ 1504 1505 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1506 if (ACPI_FAILURE (Status)) 1507 { 1508 return (Status); 1509 } 1510 1511 ParentTable = DtPeekSubtable (); 1512 DtInsertSubtable (ParentTable, Subtable); 1513 DtPopSubtable (); 1514 } 1515 1516 return (AE_OK); 1517 } 1518 1519 1520 /****************************************************************************** 1521 * 1522 * FUNCTION: DtCompileMadt 1523 * 1524 * PARAMETERS: List - Current field list pointer 1525 * 1526 * RETURN: Status 1527 * 1528 * DESCRIPTION: Compile MADT. 1529 * 1530 *****************************************************************************/ 1531 1532 ACPI_STATUS 1533 DtCompileMadt ( 1534 void **List) 1535 { 1536 ACPI_STATUS Status; 1537 DT_SUBTABLE *Subtable; 1538 DT_SUBTABLE *ParentTable; 1539 DT_FIELD **PFieldList = (DT_FIELD **) List; 1540 DT_FIELD *SubtableStart; 1541 ACPI_SUBTABLE_HEADER *MadtHeader; 1542 ACPI_DMTABLE_INFO *InfoTable; 1543 1544 1545 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt, 1546 &Subtable, TRUE); 1547 if (ACPI_FAILURE (Status)) 1548 { 1549 return (Status); 1550 } 1551 1552 ParentTable = DtPeekSubtable (); 1553 DtInsertSubtable (ParentTable, Subtable); 1554 1555 while (*PFieldList) 1556 { 1557 SubtableStart = *PFieldList; 1558 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr, 1559 &Subtable, TRUE); 1560 if (ACPI_FAILURE (Status)) 1561 { 1562 return (Status); 1563 } 1564 1565 ParentTable = DtPeekSubtable (); 1566 DtInsertSubtable (ParentTable, Subtable); 1567 DtPushSubtable (Subtable); 1568 1569 MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1570 1571 switch (MadtHeader->Type) 1572 { 1573 case ACPI_MADT_TYPE_LOCAL_APIC: 1574 1575 InfoTable = AcpiDmTableInfoMadt0; 1576 break; 1577 1578 case ACPI_MADT_TYPE_IO_APIC: 1579 1580 InfoTable = AcpiDmTableInfoMadt1; 1581 break; 1582 1583 case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: 1584 1585 InfoTable = AcpiDmTableInfoMadt2; 1586 break; 1587 1588 case ACPI_MADT_TYPE_NMI_SOURCE: 1589 1590 InfoTable = AcpiDmTableInfoMadt3; 1591 break; 1592 1593 case ACPI_MADT_TYPE_LOCAL_APIC_NMI: 1594 1595 InfoTable = AcpiDmTableInfoMadt4; 1596 break; 1597 1598 case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: 1599 1600 InfoTable = AcpiDmTableInfoMadt5; 1601 break; 1602 1603 case ACPI_MADT_TYPE_IO_SAPIC: 1604 1605 InfoTable = AcpiDmTableInfoMadt6; 1606 break; 1607 1608 case ACPI_MADT_TYPE_LOCAL_SAPIC: 1609 1610 InfoTable = AcpiDmTableInfoMadt7; 1611 break; 1612 1613 case ACPI_MADT_TYPE_INTERRUPT_SOURCE: 1614 1615 InfoTable = AcpiDmTableInfoMadt8; 1616 break; 1617 1618 case ACPI_MADT_TYPE_LOCAL_X2APIC: 1619 1620 InfoTable = AcpiDmTableInfoMadt9; 1621 break; 1622 1623 case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI: 1624 1625 InfoTable = AcpiDmTableInfoMadt10; 1626 break; 1627 1628 case ACPI_MADT_TYPE_GENERIC_INTERRUPT: 1629 1630 InfoTable = AcpiDmTableInfoMadt11; 1631 break; 1632 1633 case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR: 1634 1635 InfoTable = AcpiDmTableInfoMadt12; 1636 break; 1637 1638 case ACPI_MADT_TYPE_GENERIC_MSI_FRAME: 1639 1640 InfoTable = AcpiDmTableInfoMadt13; 1641 break; 1642 1643 case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR: 1644 1645 InfoTable = AcpiDmTableInfoMadt14; 1646 break; 1647 1648 default: 1649 1650 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT"); 1651 return (AE_ERROR); 1652 } 1653 1654 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1655 if (ACPI_FAILURE (Status)) 1656 { 1657 return (Status); 1658 } 1659 1660 ParentTable = DtPeekSubtable (); 1661 DtInsertSubtable (ParentTable, Subtable); 1662 DtPopSubtable (); 1663 } 1664 1665 return (AE_OK); 1666 } 1667 1668 1669 /****************************************************************************** 1670 * 1671 * FUNCTION: DtCompileMcfg 1672 * 1673 * PARAMETERS: List - Current field list pointer 1674 * 1675 * RETURN: Status 1676 * 1677 * DESCRIPTION: Compile MCFG. 1678 * 1679 *****************************************************************************/ 1680 1681 ACPI_STATUS 1682 DtCompileMcfg ( 1683 void **List) 1684 { 1685 ACPI_STATUS Status; 1686 1687 1688 Status = DtCompileTwoSubtables (List, 1689 AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0); 1690 return (Status); 1691 } 1692 1693 1694 /****************************************************************************** 1695 * 1696 * FUNCTION: DtCompileMpst 1697 * 1698 * PARAMETERS: List - Current field list pointer 1699 * 1700 * RETURN: Status 1701 * 1702 * DESCRIPTION: Compile MPST. 1703 * 1704 *****************************************************************************/ 1705 1706 ACPI_STATUS 1707 DtCompileMpst ( 1708 void **List) 1709 { 1710 ACPI_STATUS Status; 1711 DT_SUBTABLE *Subtable; 1712 DT_SUBTABLE *ParentTable; 1713 DT_FIELD **PFieldList = (DT_FIELD **) List; 1714 ACPI_MPST_CHANNEL *MpstChannelInfo; 1715 ACPI_MPST_POWER_NODE *MpstPowerNode; 1716 ACPI_MPST_DATA_HDR *MpstDataHeader; 1717 UINT16 SubtableCount; 1718 UINT32 PowerStateCount; 1719 UINT32 ComponentCount; 1720 1721 1722 /* Main table */ 1723 1724 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable, TRUE); 1725 if (ACPI_FAILURE (Status)) 1726 { 1727 return (Status); 1728 } 1729 1730 ParentTable = DtPeekSubtable (); 1731 DtInsertSubtable (ParentTable, Subtable); 1732 DtPushSubtable (Subtable); 1733 1734 MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer); 1735 SubtableCount = MpstChannelInfo->PowerNodeCount; 1736 1737 while (*PFieldList && SubtableCount) 1738 { 1739 /* Subtable: Memory Power Node(s) */ 1740 1741 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0, 1742 &Subtable, TRUE); 1743 if (ACPI_FAILURE (Status)) 1744 { 1745 return (Status); 1746 } 1747 1748 ParentTable = DtPeekSubtable (); 1749 DtInsertSubtable (ParentTable, Subtable); 1750 DtPushSubtable (Subtable); 1751 1752 MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer); 1753 PowerStateCount = MpstPowerNode->NumPowerStates; 1754 ComponentCount = MpstPowerNode->NumPhysicalComponents; 1755 1756 ParentTable = DtPeekSubtable (); 1757 1758 /* Sub-subtables - Memory Power State Structure(s) */ 1759 1760 while (*PFieldList && PowerStateCount) 1761 { 1762 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A, 1763 &Subtable, TRUE); 1764 if (ACPI_FAILURE (Status)) 1765 { 1766 return (Status); 1767 } 1768 1769 DtInsertSubtable (ParentTable, Subtable); 1770 PowerStateCount--; 1771 } 1772 1773 /* Sub-subtables - Physical Component ID Structure(s) */ 1774 1775 while (*PFieldList && ComponentCount) 1776 { 1777 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B, 1778 &Subtable, TRUE); 1779 if (ACPI_FAILURE (Status)) 1780 { 1781 return (Status); 1782 } 1783 1784 DtInsertSubtable (ParentTable, Subtable); 1785 ComponentCount--; 1786 } 1787 1788 SubtableCount--; 1789 DtPopSubtable (); 1790 } 1791 1792 /* Subtable: Count of Memory Power State Characteristic structures */ 1793 1794 DtPopSubtable (); 1795 1796 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable, TRUE); 1797 if (ACPI_FAILURE (Status)) 1798 { 1799 return (Status); 1800 } 1801 1802 ParentTable = DtPeekSubtable (); 1803 DtInsertSubtable (ParentTable, Subtable); 1804 DtPushSubtable (Subtable); 1805 1806 MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer); 1807 SubtableCount = MpstDataHeader->CharacteristicsCount; 1808 1809 ParentTable = DtPeekSubtable (); 1810 1811 /* Subtable: Memory Power State Characteristics structure(s) */ 1812 1813 while (*PFieldList && SubtableCount) 1814 { 1815 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2, 1816 &Subtable, TRUE); 1817 if (ACPI_FAILURE (Status)) 1818 { 1819 return (Status); 1820 } 1821 1822 DtInsertSubtable (ParentTable, Subtable); 1823 SubtableCount--; 1824 } 1825 1826 DtPopSubtable (); 1827 return (AE_OK); 1828 } 1829 1830 1831 /****************************************************************************** 1832 * 1833 * FUNCTION: DtCompileMsct 1834 * 1835 * PARAMETERS: List - Current field list pointer 1836 * 1837 * RETURN: Status 1838 * 1839 * DESCRIPTION: Compile MSCT. 1840 * 1841 *****************************************************************************/ 1842 1843 ACPI_STATUS 1844 DtCompileMsct ( 1845 void **List) 1846 { 1847 ACPI_STATUS Status; 1848 1849 1850 Status = DtCompileTwoSubtables (List, 1851 AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0); 1852 return (Status); 1853 } 1854 1855 1856 /****************************************************************************** 1857 * 1858 * FUNCTION: DtCompileMtmr 1859 * 1860 * PARAMETERS: List - Current field list pointer 1861 * 1862 * RETURN: Status 1863 * 1864 * DESCRIPTION: Compile MTMR. 1865 * 1866 *****************************************************************************/ 1867 1868 ACPI_STATUS 1869 DtCompileMtmr ( 1870 void **List) 1871 { 1872 ACPI_STATUS Status; 1873 1874 1875 Status = DtCompileTwoSubtables (List, 1876 AcpiDmTableInfoMtmr, AcpiDmTableInfoMtmr0); 1877 return (Status); 1878 } 1879 1880 1881 /****************************************************************************** 1882 * 1883 * FUNCTION: DtCompilePcct 1884 * 1885 * PARAMETERS: List - Current field list pointer 1886 * 1887 * RETURN: Status 1888 * 1889 * DESCRIPTION: Compile PCCT. 1890 * 1891 *****************************************************************************/ 1892 1893 ACPI_STATUS 1894 DtCompilePcct ( 1895 void **List) 1896 { 1897 ACPI_STATUS Status; 1898 DT_SUBTABLE *Subtable; 1899 DT_SUBTABLE *ParentTable; 1900 DT_FIELD **PFieldList = (DT_FIELD **) List; 1901 DT_FIELD *SubtableStart; 1902 ACPI_SUBTABLE_HEADER *PcctHeader; 1903 ACPI_DMTABLE_INFO *InfoTable; 1904 1905 1906 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct, 1907 &Subtable, TRUE); 1908 if (ACPI_FAILURE (Status)) 1909 { 1910 return (Status); 1911 } 1912 1913 ParentTable = DtPeekSubtable (); 1914 DtInsertSubtable (ParentTable, Subtable); 1915 1916 while (*PFieldList) 1917 { 1918 SubtableStart = *PFieldList; 1919 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr, 1920 &Subtable, TRUE); 1921 if (ACPI_FAILURE (Status)) 1922 { 1923 return (Status); 1924 } 1925 1926 ParentTable = DtPeekSubtable (); 1927 DtInsertSubtable (ParentTable, Subtable); 1928 DtPushSubtable (Subtable); 1929 1930 PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1931 1932 switch (PcctHeader->Type) 1933 { 1934 case ACPI_PCCT_TYPE_GENERIC_SUBSPACE: 1935 1936 InfoTable = AcpiDmTableInfoPcct0; 1937 break; 1938 1939 case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE: 1940 1941 InfoTable = AcpiDmTableInfoPcct1; 1942 break; 1943 1944 default: 1945 1946 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT"); 1947 return (AE_ERROR); 1948 } 1949 1950 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1951 if (ACPI_FAILURE (Status)) 1952 { 1953 return (Status); 1954 } 1955 1956 ParentTable = DtPeekSubtable (); 1957 DtInsertSubtable (ParentTable, Subtable); 1958 DtPopSubtable (); 1959 } 1960 1961 return (AE_OK); 1962 } 1963 1964 1965 /****************************************************************************** 1966 * 1967 * FUNCTION: DtCompilePmtt 1968 * 1969 * PARAMETERS: List - Current field list pointer 1970 * 1971 * RETURN: Status 1972 * 1973 * DESCRIPTION: Compile PMTT. 1974 * 1975 *****************************************************************************/ 1976 1977 ACPI_STATUS 1978 DtCompilePmtt ( 1979 void **List) 1980 { 1981 ACPI_STATUS Status; 1982 DT_SUBTABLE *Subtable; 1983 DT_SUBTABLE *ParentTable; 1984 DT_FIELD **PFieldList = (DT_FIELD **) List; 1985 DT_FIELD *SubtableStart; 1986 ACPI_PMTT_HEADER *PmttHeader; 1987 ACPI_PMTT_CONTROLLER *PmttController; 1988 UINT16 DomainCount; 1989 UINT8 PrevType = ACPI_PMTT_TYPE_SOCKET; 1990 1991 1992 /* Main table */ 1993 1994 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable, TRUE); 1995 if (ACPI_FAILURE (Status)) 1996 { 1997 return (Status); 1998 } 1999 2000 ParentTable = DtPeekSubtable (); 2001 DtInsertSubtable (ParentTable, Subtable); 2002 DtPushSubtable (Subtable); 2003 2004 while (*PFieldList) 2005 { 2006 SubtableStart = *PFieldList; 2007 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttHdr, 2008 &Subtable, TRUE); 2009 if (ACPI_FAILURE (Status)) 2010 { 2011 return (Status); 2012 } 2013 2014 PmttHeader = ACPI_CAST_PTR (ACPI_PMTT_HEADER, Subtable->Buffer); 2015 while (PrevType >= PmttHeader->Type) 2016 { 2017 DtPopSubtable (); 2018 2019 if (PrevType == ACPI_PMTT_TYPE_SOCKET) 2020 { 2021 break; 2022 } 2023 PrevType--; 2024 } 2025 PrevType = PmttHeader->Type; 2026 2027 ParentTable = DtPeekSubtable (); 2028 DtInsertSubtable (ParentTable, Subtable); 2029 DtPushSubtable (Subtable); 2030 2031 switch (PmttHeader->Type) 2032 { 2033 case ACPI_PMTT_TYPE_SOCKET: 2034 2035 /* Subtable: Socket Structure */ 2036 2037 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0, 2038 &Subtable, TRUE); 2039 if (ACPI_FAILURE (Status)) 2040 { 2041 return (Status); 2042 } 2043 2044 ParentTable = DtPeekSubtable (); 2045 DtInsertSubtable (ParentTable, Subtable); 2046 break; 2047 2048 case ACPI_PMTT_TYPE_CONTROLLER: 2049 2050 /* Subtable: Memory Controller Structure */ 2051 2052 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1, 2053 &Subtable, TRUE); 2054 if (ACPI_FAILURE (Status)) 2055 { 2056 return (Status); 2057 } 2058 2059 ParentTable = DtPeekSubtable (); 2060 DtInsertSubtable (ParentTable, Subtable); 2061 2062 PmttController = ACPI_CAST_PTR (ACPI_PMTT_CONTROLLER, 2063 (Subtable->Buffer - sizeof (ACPI_PMTT_HEADER))); 2064 DomainCount = PmttController->DomainCount; 2065 2066 while (DomainCount) 2067 { 2068 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1a, 2069 &Subtable, TRUE); 2070 if (ACPI_FAILURE (Status)) 2071 { 2072 return (Status); 2073 } 2074 2075 DtInsertSubtable (ParentTable, Subtable); 2076 DomainCount--; 2077 } 2078 break; 2079 2080 case ACPI_PMTT_TYPE_DIMM: 2081 2082 /* Subtable: Physical Component Structure */ 2083 2084 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2, 2085 &Subtable, TRUE); 2086 if (ACPI_FAILURE (Status)) 2087 { 2088 return (Status); 2089 } 2090 2091 ParentTable = DtPeekSubtable (); 2092 DtInsertSubtable (ParentTable, Subtable); 2093 break; 2094 2095 default: 2096 2097 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT"); 2098 return (AE_ERROR); 2099 } 2100 } 2101 2102 return (Status); 2103 } 2104 2105 2106 /****************************************************************************** 2107 * 2108 * FUNCTION: DtCompileRsdt 2109 * 2110 * PARAMETERS: List - Current field list pointer 2111 * 2112 * RETURN: Status 2113 * 2114 * DESCRIPTION: Compile RSDT. 2115 * 2116 *****************************************************************************/ 2117 2118 ACPI_STATUS 2119 DtCompileRsdt ( 2120 void **List) 2121 { 2122 DT_SUBTABLE *Subtable; 2123 DT_SUBTABLE *ParentTable; 2124 DT_FIELD *FieldList = *(DT_FIELD **) List; 2125 UINT32 Address; 2126 2127 2128 ParentTable = DtPeekSubtable (); 2129 2130 while (FieldList) 2131 { 2132 DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO); 2133 2134 DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable); 2135 DtInsertSubtable (ParentTable, Subtable); 2136 FieldList = FieldList->Next; 2137 } 2138 2139 return (AE_OK); 2140 } 2141 2142 2143 /****************************************************************************** 2144 * 2145 * FUNCTION: DtCompileS3pt 2146 * 2147 * PARAMETERS: PFieldList - Current field list pointer 2148 * 2149 * RETURN: Status 2150 * 2151 * DESCRIPTION: Compile S3PT (Pointed to by FPDT) 2152 * 2153 *****************************************************************************/ 2154 2155 ACPI_STATUS 2156 DtCompileS3pt ( 2157 DT_FIELD **PFieldList) 2158 { 2159 ACPI_STATUS Status; 2160 ACPI_S3PT_HEADER *S3ptHeader; 2161 DT_SUBTABLE *Subtable; 2162 DT_SUBTABLE *ParentTable; 2163 ACPI_DMTABLE_INFO *InfoTable; 2164 DT_FIELD *SubtableStart; 2165 2166 2167 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt, 2168 &Gbl_RootTable, TRUE); 2169 if (ACPI_FAILURE (Status)) 2170 { 2171 return (Status); 2172 } 2173 2174 DtPushSubtable (Gbl_RootTable); 2175 2176 while (*PFieldList) 2177 { 2178 SubtableStart = *PFieldList; 2179 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr, 2180 &Subtable, TRUE); 2181 if (ACPI_FAILURE (Status)) 2182 { 2183 return (Status); 2184 } 2185 2186 ParentTable = DtPeekSubtable (); 2187 DtInsertSubtable (ParentTable, Subtable); 2188 DtPushSubtable (Subtable); 2189 2190 S3ptHeader = ACPI_CAST_PTR (ACPI_S3PT_HEADER, Subtable->Buffer); 2191 2192 switch (S3ptHeader->Type) 2193 { 2194 case ACPI_S3PT_TYPE_RESUME: 2195 2196 InfoTable = AcpiDmTableInfoS3pt0; 2197 break; 2198 2199 case ACPI_S3PT_TYPE_SUSPEND: 2200 2201 InfoTable = AcpiDmTableInfoS3pt1; 2202 break; 2203 2204 default: 2205 2206 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT"); 2207 return (AE_ERROR); 2208 } 2209 2210 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 2211 if (ACPI_FAILURE (Status)) 2212 { 2213 return (Status); 2214 } 2215 2216 ParentTable = DtPeekSubtable (); 2217 DtInsertSubtable (ParentTable, Subtable); 2218 DtPopSubtable (); 2219 } 2220 2221 return (AE_OK); 2222 } 2223 2224 2225 /****************************************************************************** 2226 * 2227 * FUNCTION: DtCompileSlic 2228 * 2229 * PARAMETERS: List - Current field list pointer 2230 * 2231 * RETURN: Status 2232 * 2233 * DESCRIPTION: Compile SLIC. 2234 * 2235 *****************************************************************************/ 2236 2237 ACPI_STATUS 2238 DtCompileSlic ( 2239 void **List) 2240 { 2241 ACPI_STATUS Status; 2242 DT_SUBTABLE *Subtable; 2243 DT_SUBTABLE *ParentTable; 2244 DT_FIELD **PFieldList = (DT_FIELD **) List; 2245 DT_FIELD *SubtableStart; 2246 ACPI_SLIC_HEADER *SlicHeader; 2247 ACPI_DMTABLE_INFO *InfoTable; 2248 2249 2250 while (*PFieldList) 2251 { 2252 SubtableStart = *PFieldList; 2253 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlicHdr, 2254 &Subtable, TRUE); 2255 if (ACPI_FAILURE (Status)) 2256 { 2257 return (Status); 2258 } 2259 2260 ParentTable = DtPeekSubtable (); 2261 DtInsertSubtable (ParentTable, Subtable); 2262 DtPushSubtable (Subtable); 2263 2264 SlicHeader = ACPI_CAST_PTR (ACPI_SLIC_HEADER, Subtable->Buffer); 2265 2266 switch (SlicHeader->Type) 2267 { 2268 case ACPI_SLIC_TYPE_PUBLIC_KEY: 2269 2270 InfoTable = AcpiDmTableInfoSlic0; 2271 break; 2272 2273 case ACPI_SLIC_TYPE_WINDOWS_MARKER: 2274 2275 InfoTable = AcpiDmTableInfoSlic1; 2276 break; 2277 2278 default: 2279 2280 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SLIC"); 2281 return (AE_ERROR); 2282 } 2283 2284 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 2285 if (ACPI_FAILURE (Status)) 2286 { 2287 return (Status); 2288 } 2289 2290 ParentTable = DtPeekSubtable (); 2291 DtInsertSubtable (ParentTable, Subtable); 2292 DtPopSubtable (); 2293 } 2294 2295 return (AE_OK); 2296 } 2297 2298 2299 /****************************************************************************** 2300 * 2301 * FUNCTION: DtCompileSlit 2302 * 2303 * PARAMETERS: List - Current field list pointer 2304 * 2305 * RETURN: Status 2306 * 2307 * DESCRIPTION: Compile SLIT. 2308 * 2309 *****************************************************************************/ 2310 2311 ACPI_STATUS 2312 DtCompileSlit ( 2313 void **List) 2314 { 2315 ACPI_STATUS Status; 2316 DT_SUBTABLE *Subtable; 2317 DT_SUBTABLE *ParentTable; 2318 DT_FIELD **PFieldList = (DT_FIELD **) List; 2319 DT_FIELD *FieldList; 2320 UINT32 Localities; 2321 UINT8 *LocalityBuffer; 2322 2323 2324 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit, 2325 &Subtable, TRUE); 2326 if (ACPI_FAILURE (Status)) 2327 { 2328 return (Status); 2329 } 2330 2331 ParentTable = DtPeekSubtable (); 2332 DtInsertSubtable (ParentTable, Subtable); 2333 2334 Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer); 2335 LocalityBuffer = UtLocalCalloc (Localities); 2336 2337 /* Compile each locality buffer */ 2338 2339 FieldList = *PFieldList; 2340 while (FieldList) 2341 { 2342 DtCompileBuffer (LocalityBuffer, 2343 FieldList->Value, FieldList, Localities); 2344 2345 DtCreateSubtable (LocalityBuffer, Localities, &Subtable); 2346 DtInsertSubtable (ParentTable, Subtable); 2347 FieldList = FieldList->Next; 2348 } 2349 2350 ACPI_FREE (LocalityBuffer); 2351 return (AE_OK); 2352 } 2353 2354 2355 /****************************************************************************** 2356 * 2357 * FUNCTION: DtCompileSrat 2358 * 2359 * PARAMETERS: List - Current field list pointer 2360 * 2361 * RETURN: Status 2362 * 2363 * DESCRIPTION: Compile SRAT. 2364 * 2365 *****************************************************************************/ 2366 2367 ACPI_STATUS 2368 DtCompileSrat ( 2369 void **List) 2370 { 2371 ACPI_STATUS Status; 2372 DT_SUBTABLE *Subtable; 2373 DT_SUBTABLE *ParentTable; 2374 DT_FIELD **PFieldList = (DT_FIELD **) List; 2375 DT_FIELD *SubtableStart; 2376 ACPI_SUBTABLE_HEADER *SratHeader; 2377 ACPI_DMTABLE_INFO *InfoTable; 2378 2379 2380 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat, 2381 &Subtable, TRUE); 2382 if (ACPI_FAILURE (Status)) 2383 { 2384 return (Status); 2385 } 2386 2387 ParentTable = DtPeekSubtable (); 2388 DtInsertSubtable (ParentTable, Subtable); 2389 2390 while (*PFieldList) 2391 { 2392 SubtableStart = *PFieldList; 2393 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr, 2394 &Subtable, TRUE); 2395 if (ACPI_FAILURE (Status)) 2396 { 2397 return (Status); 2398 } 2399 2400 ParentTable = DtPeekSubtable (); 2401 DtInsertSubtable (ParentTable, Subtable); 2402 DtPushSubtable (Subtable); 2403 2404 SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 2405 2406 switch (SratHeader->Type) 2407 { 2408 case ACPI_SRAT_TYPE_CPU_AFFINITY: 2409 2410 InfoTable = AcpiDmTableInfoSrat0; 2411 break; 2412 2413 case ACPI_SRAT_TYPE_MEMORY_AFFINITY: 2414 2415 InfoTable = AcpiDmTableInfoSrat1; 2416 break; 2417 2418 case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: 2419 2420 InfoTable = AcpiDmTableInfoSrat2; 2421 break; 2422 2423 case ACPI_SRAT_TYPE_GICC_AFFINITY: 2424 2425 InfoTable = AcpiDmTableInfoSrat3; 2426 break; 2427 2428 default: 2429 2430 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT"); 2431 return (AE_ERROR); 2432 } 2433 2434 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 2435 if (ACPI_FAILURE (Status)) 2436 { 2437 return (Status); 2438 } 2439 2440 ParentTable = DtPeekSubtable (); 2441 DtInsertSubtable (ParentTable, Subtable); 2442 DtPopSubtable (); 2443 } 2444 2445 return (AE_OK); 2446 } 2447 2448 2449 /****************************************************************************** 2450 * 2451 * FUNCTION: DtGetGenericTableInfo 2452 * 2453 * PARAMETERS: Name - Generic type name 2454 * 2455 * RETURN: Info entry 2456 * 2457 * DESCRIPTION: Obtain table info for a generic name entry 2458 * 2459 *****************************************************************************/ 2460 2461 ACPI_DMTABLE_INFO * 2462 DtGetGenericTableInfo ( 2463 char *Name) 2464 { 2465 ACPI_DMTABLE_INFO *Info; 2466 UINT32 i; 2467 2468 2469 if (!Name) 2470 { 2471 return (NULL); 2472 } 2473 2474 /* Search info table for name match */ 2475 2476 for (i = 0; ; i++) 2477 { 2478 Info = AcpiDmTableInfoGeneric[i]; 2479 if (Info->Opcode == ACPI_DMT_EXIT) 2480 { 2481 Info = NULL; 2482 break; 2483 } 2484 2485 /* Use caseless compare for generic keywords */ 2486 2487 if (!AcpiUtStricmp (Name, Info->Name)) 2488 { 2489 break; 2490 } 2491 } 2492 2493 return (Info); 2494 } 2495 2496 2497 /****************************************************************************** 2498 * 2499 * FUNCTION: DtCompileUefi 2500 * 2501 * PARAMETERS: List - Current field list pointer 2502 * 2503 * RETURN: Status 2504 * 2505 * DESCRIPTION: Compile UEFI. 2506 * 2507 *****************************************************************************/ 2508 2509 ACPI_STATUS 2510 DtCompileUefi ( 2511 void **List) 2512 { 2513 ACPI_STATUS Status; 2514 DT_SUBTABLE *Subtable; 2515 DT_SUBTABLE *ParentTable; 2516 DT_FIELD **PFieldList = (DT_FIELD **) List; 2517 UINT16 *DataOffset; 2518 2519 2520 /* Compile the predefined portion of the UEFI table */ 2521 2522 Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi, 2523 &Subtable, TRUE); 2524 if (ACPI_FAILURE (Status)) 2525 { 2526 return (Status); 2527 } 2528 2529 DataOffset = (UINT16 *) (Subtable->Buffer + 16); 2530 *DataOffset = sizeof (ACPI_TABLE_UEFI); 2531 2532 ParentTable = DtPeekSubtable (); 2533 DtInsertSubtable (ParentTable, Subtable); 2534 2535 /* 2536 * Compile the "generic" portion of the UEFI table. This 2537 * part of the table is not predefined and any of the generic 2538 * operators may be used. 2539 */ 2540 2541 DtCompileGeneric ((void **) PFieldList); 2542 2543 return (AE_OK); 2544 } 2545 2546 2547 /****************************************************************************** 2548 * 2549 * FUNCTION: DtCompileVrtc 2550 * 2551 * PARAMETERS: List - Current field list pointer 2552 * 2553 * RETURN: Status 2554 * 2555 * DESCRIPTION: Compile VRTC. 2556 * 2557 *****************************************************************************/ 2558 2559 ACPI_STATUS 2560 DtCompileVrtc ( 2561 void **List) 2562 { 2563 ACPI_STATUS Status; 2564 2565 2566 Status = DtCompileTwoSubtables (List, 2567 AcpiDmTableInfoVrtc, AcpiDmTableInfoVrtc0); 2568 return (Status); 2569 } 2570 2571 2572 /****************************************************************************** 2573 * 2574 * FUNCTION: DtCompileWdat 2575 * 2576 * PARAMETERS: List - Current field list pointer 2577 * 2578 * RETURN: Status 2579 * 2580 * DESCRIPTION: Compile WDAT. 2581 * 2582 *****************************************************************************/ 2583 2584 ACPI_STATUS 2585 DtCompileWdat ( 2586 void **List) 2587 { 2588 ACPI_STATUS Status; 2589 2590 2591 Status = DtCompileTwoSubtables (List, 2592 AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0); 2593 return (Status); 2594 } 2595 2596 2597 /****************************************************************************** 2598 * 2599 * FUNCTION: DtCompileXsdt 2600 * 2601 * PARAMETERS: List - Current field list pointer 2602 * 2603 * RETURN: Status 2604 * 2605 * DESCRIPTION: Compile XSDT. 2606 * 2607 *****************************************************************************/ 2608 2609 ACPI_STATUS 2610 DtCompileXsdt ( 2611 void **List) 2612 { 2613 DT_SUBTABLE *Subtable; 2614 DT_SUBTABLE *ParentTable; 2615 DT_FIELD *FieldList = *(DT_FIELD **) List; 2616 UINT64 Address; 2617 2618 ParentTable = DtPeekSubtable (); 2619 2620 while (FieldList) 2621 { 2622 DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO); 2623 2624 DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable); 2625 DtInsertSubtable (ParentTable, Subtable); 2626 FieldList = FieldList->Next; 2627 } 2628 2629 return (AE_OK); 2630 } 2631 2632 2633 /****************************************************************************** 2634 * 2635 * FUNCTION: DtCompileGeneric 2636 * 2637 * PARAMETERS: List - Current field list pointer 2638 * 2639 * RETURN: Status 2640 * 2641 * DESCRIPTION: Compile generic unknown table. 2642 * 2643 *****************************************************************************/ 2644 2645 ACPI_STATUS 2646 DtCompileGeneric ( 2647 void **List) 2648 { 2649 ACPI_STATUS Status; 2650 DT_SUBTABLE *Subtable; 2651 DT_SUBTABLE *ParentTable; 2652 DT_FIELD **PFieldList = (DT_FIELD **) List; 2653 ACPI_DMTABLE_INFO *Info; 2654 2655 2656 ParentTable = DtPeekSubtable (); 2657 2658 /* 2659 * Compile the "generic" portion of the table. This 2660 * part of the table is not predefined and any of the generic 2661 * operators may be used. 2662 */ 2663 2664 /* Find any and all labels in the entire generic portion */ 2665 2666 DtDetectAllLabels (*PFieldList); 2667 2668 /* Now we can actually compile the parse tree */ 2669 2670 while (*PFieldList) 2671 { 2672 Info = DtGetGenericTableInfo ((*PFieldList)->Name); 2673 if (!Info) 2674 { 2675 sprintf (MsgBuffer, "Generic data type \"%s\" not found", 2676 (*PFieldList)->Name); 2677 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 2678 (*PFieldList), MsgBuffer); 2679 2680 *PFieldList = (*PFieldList)->Next; 2681 continue; 2682 } 2683 2684 Status = DtCompileTable (PFieldList, Info, 2685 &Subtable, TRUE); 2686 if (ACPI_SUCCESS (Status)) 2687 { 2688 DtInsertSubtable (ParentTable, Subtable); 2689 } 2690 else 2691 { 2692 *PFieldList = (*PFieldList)->Next; 2693 2694 if (Status == AE_NOT_FOUND) 2695 { 2696 sprintf (MsgBuffer, "Generic data type \"%s\" not found", 2697 (*PFieldList)->Name); 2698 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 2699 (*PFieldList), MsgBuffer); 2700 } 2701 } 2702 } 2703 2704 return (AE_OK); 2705 } 2706