1 /****************************************************************************** 2 * 3 * Module Name: dttable.c - handling for specific ACPI tables 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2015, 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 /* Compile all complex data tables */ 45 46 #include <contrib/dev/acpica/compiler/aslcompiler.h> 47 #include <contrib/dev/acpica/compiler/dtcompiler.h> 48 49 #define _COMPONENT DT_COMPILER 50 ACPI_MODULE_NAME ("dttable") 51 52 53 /* TBD: merge these into dmtbinfo.c? */ 54 55 static ACPI_DMTABLE_INFO TableInfoAsfAddress[] = 56 { 57 {ACPI_DMT_BUFFER, 0, "Addresses", 0}, 58 {ACPI_DMT_EXIT, 0, NULL, 0} 59 }; 60 61 static ACPI_DMTABLE_INFO TableInfoDmarPciPath[] = 62 { 63 {ACPI_DMT_PCI_PATH, 0, "PCI Path", 0}, 64 {ACPI_DMT_EXIT, 0, NULL, 0} 65 }; 66 67 68 /* Local prototypes */ 69 70 static ACPI_STATUS 71 DtCompileTwoSubtables ( 72 void **List, 73 ACPI_DMTABLE_INFO *TableInfo1, 74 ACPI_DMTABLE_INFO *TableInfo2); 75 76 77 /****************************************************************************** 78 * 79 * FUNCTION: DtCompileTwoSubtables 80 * 81 * PARAMETERS: List - Current field list pointer 82 * TableInfo1 - Info table 1 83 * TableInfo1 - Info table 2 84 * 85 * RETURN: Status 86 * 87 * DESCRIPTION: Compile tables with a header and one or more same subtables. 88 * Include CPEP, EINJ, ERST, MCFG, MSCT, WDAT 89 * 90 *****************************************************************************/ 91 92 static ACPI_STATUS 93 DtCompileTwoSubtables ( 94 void **List, 95 ACPI_DMTABLE_INFO *TableInfo1, 96 ACPI_DMTABLE_INFO *TableInfo2) 97 { 98 ACPI_STATUS Status; 99 DT_SUBTABLE *Subtable; 100 DT_SUBTABLE *ParentTable; 101 DT_FIELD **PFieldList = (DT_FIELD **) List; 102 103 104 Status = DtCompileTable (PFieldList, TableInfo1, &Subtable, TRUE); 105 if (ACPI_FAILURE (Status)) 106 { 107 return (Status); 108 } 109 110 ParentTable = DtPeekSubtable (); 111 DtInsertSubtable (ParentTable, Subtable); 112 113 while (*PFieldList) 114 { 115 Status = DtCompileTable (PFieldList, TableInfo2, &Subtable, FALSE); 116 if (ACPI_FAILURE (Status)) 117 { 118 return (Status); 119 } 120 121 DtInsertSubtable (ParentTable, Subtable); 122 } 123 124 return (AE_OK); 125 } 126 127 128 /****************************************************************************** 129 * 130 * FUNCTION: DtCompileFacs 131 * 132 * PARAMETERS: PFieldList - Current field list pointer 133 * 134 * RETURN: Status 135 * 136 * DESCRIPTION: Compile FACS. 137 * 138 *****************************************************************************/ 139 140 ACPI_STATUS 141 DtCompileFacs ( 142 DT_FIELD **PFieldList) 143 { 144 DT_SUBTABLE *Subtable; 145 UINT8 *ReservedBuffer; 146 ACPI_STATUS Status; 147 UINT32 ReservedSize; 148 149 150 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFacs, 151 &Gbl_RootTable, TRUE); 152 if (ACPI_FAILURE (Status)) 153 { 154 return (Status); 155 } 156 157 /* Large FACS reserved area at the end of the table */ 158 159 ReservedSize = (UINT32) sizeof (((ACPI_TABLE_FACS *) NULL)->Reserved1); 160 ReservedBuffer = UtLocalCalloc (ReservedSize); 161 162 DtCreateSubtable (ReservedBuffer, ReservedSize, &Subtable); 163 164 ACPI_FREE (ReservedBuffer); 165 DtInsertSubtable (Gbl_RootTable, Subtable); 166 return (AE_OK); 167 } 168 169 170 /****************************************************************************** 171 * 172 * FUNCTION: DtCompileRsdp 173 * 174 * PARAMETERS: PFieldList - Current field list pointer 175 * 176 * RETURN: Status 177 * 178 * DESCRIPTION: Compile RSDP. 179 * 180 *****************************************************************************/ 181 182 ACPI_STATUS 183 DtCompileRsdp ( 184 DT_FIELD **PFieldList) 185 { 186 DT_SUBTABLE *Subtable; 187 ACPI_TABLE_RSDP *Rsdp; 188 ACPI_RSDP_EXTENSION *RsdpExtension; 189 ACPI_STATUS Status; 190 191 192 /* Compile the "common" RSDP (ACPI 1.0) */ 193 194 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp1, 195 &Gbl_RootTable, TRUE); 196 if (ACPI_FAILURE (Status)) 197 { 198 return (Status); 199 } 200 201 Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Gbl_RootTable->Buffer); 202 DtSetTableChecksum (&Rsdp->Checksum); 203 204 if (Rsdp->Revision > 0) 205 { 206 /* Compile the "extended" part of the RSDP as a subtable */ 207 208 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp2, 209 &Subtable, TRUE); 210 if (ACPI_FAILURE (Status)) 211 { 212 return (Status); 213 } 214 215 DtInsertSubtable (Gbl_RootTable, Subtable); 216 217 /* Set length and extended checksum for entire RSDP */ 218 219 RsdpExtension = ACPI_CAST_PTR (ACPI_RSDP_EXTENSION, Subtable->Buffer); 220 RsdpExtension->Length = Gbl_RootTable->Length + Subtable->Length; 221 DtSetTableChecksum (&RsdpExtension->ExtendedChecksum); 222 } 223 224 return (AE_OK); 225 } 226 227 228 /****************************************************************************** 229 * 230 * FUNCTION: DtCompileAsf 231 * 232 * PARAMETERS: List - Current field list pointer 233 * 234 * RETURN: Status 235 * 236 * DESCRIPTION: Compile ASF!. 237 * 238 *****************************************************************************/ 239 240 ACPI_STATUS 241 DtCompileAsf ( 242 void **List) 243 { 244 ACPI_ASF_INFO *AsfTable; 245 DT_SUBTABLE *Subtable; 246 DT_SUBTABLE *ParentTable; 247 ACPI_DMTABLE_INFO *InfoTable; 248 ACPI_DMTABLE_INFO *DataInfoTable = NULL; 249 UINT32 DataCount = 0; 250 ACPI_STATUS Status; 251 UINT32 i; 252 DT_FIELD **PFieldList = (DT_FIELD **) List; 253 DT_FIELD *SubtableStart; 254 255 256 while (*PFieldList) 257 { 258 SubtableStart = *PFieldList; 259 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr, 260 &Subtable, TRUE); 261 if (ACPI_FAILURE (Status)) 262 { 263 return (Status); 264 } 265 266 ParentTable = DtPeekSubtable (); 267 DtInsertSubtable (ParentTable, Subtable); 268 DtPushSubtable (Subtable); 269 270 AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer); 271 272 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */ 273 { 274 case ACPI_ASF_TYPE_INFO: 275 276 InfoTable = AcpiDmTableInfoAsf0; 277 break; 278 279 case ACPI_ASF_TYPE_ALERT: 280 281 InfoTable = AcpiDmTableInfoAsf1; 282 break; 283 284 case ACPI_ASF_TYPE_CONTROL: 285 286 InfoTable = AcpiDmTableInfoAsf2; 287 break; 288 289 case ACPI_ASF_TYPE_BOOT: 290 291 InfoTable = AcpiDmTableInfoAsf3; 292 break; 293 294 case ACPI_ASF_TYPE_ADDRESS: 295 296 InfoTable = AcpiDmTableInfoAsf4; 297 break; 298 299 default: 300 301 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); 302 return (AE_ERROR); 303 } 304 305 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 306 if (ACPI_FAILURE (Status)) 307 { 308 return (Status); 309 } 310 311 ParentTable = DtPeekSubtable (); 312 DtInsertSubtable (ParentTable, Subtable); 313 314 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */ 315 { 316 case ACPI_ASF_TYPE_INFO: 317 318 DataInfoTable = NULL; 319 break; 320 321 case ACPI_ASF_TYPE_ALERT: 322 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 331 DataInfoTable = AcpiDmTableInfoAsf2a; 332 DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, 333 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 334 sizeof (ACPI_ASF_HEADER)))->Controls; 335 break; 336 337 case ACPI_ASF_TYPE_BOOT: 338 339 DataInfoTable = NULL; 340 break; 341 342 case ACPI_ASF_TYPE_ADDRESS: 343 344 DataInfoTable = TableInfoAsfAddress; 345 DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, 346 ACPI_SUB_PTR (UINT8, Subtable->Buffer, 347 sizeof (ACPI_ASF_HEADER)))->Devices; 348 break; 349 350 default: 351 352 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); 353 return (AE_ERROR); 354 } 355 356 if (DataInfoTable) 357 { 358 switch (AsfTable->Header.Type & 0x7F) 359 { 360 case ACPI_ASF_TYPE_ADDRESS: 361 362 while (DataCount > 0) 363 { 364 Status = DtCompileTable (PFieldList, DataInfoTable, 365 &Subtable, TRUE); 366 if (ACPI_FAILURE (Status)) 367 { 368 return (Status); 369 } 370 371 DtInsertSubtable (ParentTable, Subtable); 372 DataCount = DataCount - Subtable->Length; 373 } 374 break; 375 376 default: 377 378 for (i = 0; i < DataCount; i++) 379 { 380 Status = DtCompileTable (PFieldList, DataInfoTable, 381 &Subtable, TRUE); 382 if (ACPI_FAILURE (Status)) 383 { 384 return (Status); 385 } 386 387 DtInsertSubtable (ParentTable, Subtable); 388 } 389 break; 390 } 391 } 392 393 DtPopSubtable (); 394 } 395 396 return (AE_OK); 397 } 398 399 400 /****************************************************************************** 401 * 402 * FUNCTION: DtCompileCpep 403 * 404 * PARAMETERS: List - Current field list pointer 405 * 406 * RETURN: Status 407 * 408 * DESCRIPTION: Compile CPEP. 409 * 410 *****************************************************************************/ 411 412 ACPI_STATUS 413 DtCompileCpep ( 414 void **List) 415 { 416 ACPI_STATUS Status; 417 418 419 Status = DtCompileTwoSubtables (List, 420 AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0); 421 return (Status); 422 } 423 424 425 /****************************************************************************** 426 * 427 * FUNCTION: DtCompileCsrt 428 * 429 * PARAMETERS: List - Current field list pointer 430 * 431 * RETURN: Status 432 * 433 * DESCRIPTION: Compile CSRT. 434 * 435 *****************************************************************************/ 436 437 ACPI_STATUS 438 DtCompileCsrt ( 439 void **List) 440 { 441 ACPI_STATUS Status = AE_OK; 442 DT_SUBTABLE *Subtable; 443 DT_SUBTABLE *ParentTable; 444 DT_FIELD **PFieldList = (DT_FIELD **) List; 445 UINT32 DescriptorCount; 446 UINT32 GroupLength; 447 448 449 /* Subtables (Resource Groups) */ 450 451 ParentTable = DtPeekSubtable (); 452 while (*PFieldList) 453 { 454 /* Resource group subtable */ 455 456 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0, 457 &Subtable, TRUE); 458 if (ACPI_FAILURE (Status)) 459 { 460 return (Status); 461 } 462 463 /* Compute the number of resource descriptors */ 464 465 GroupLength = 466 (ACPI_CAST_PTR (ACPI_CSRT_GROUP, 467 Subtable->Buffer))->Length - 468 (ACPI_CAST_PTR (ACPI_CSRT_GROUP, 469 Subtable->Buffer))->SharedInfoLength - 470 sizeof (ACPI_CSRT_GROUP); 471 472 DescriptorCount = (GroupLength / 473 sizeof (ACPI_CSRT_DESCRIPTOR)); 474 475 DtInsertSubtable (ParentTable, Subtable); 476 DtPushSubtable (Subtable); 477 ParentTable = DtPeekSubtable (); 478 479 /* Shared info subtable (One per resource group) */ 480 481 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1, 482 &Subtable, TRUE); 483 if (ACPI_FAILURE (Status)) 484 { 485 return (Status); 486 } 487 488 DtInsertSubtable (ParentTable, Subtable); 489 490 /* Sub-Subtables (Resource Descriptors) */ 491 492 while (*PFieldList && DescriptorCount) 493 { 494 495 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2, 496 &Subtable, TRUE); 497 if (ACPI_FAILURE (Status)) 498 { 499 return (Status); 500 } 501 DtInsertSubtable (ParentTable, Subtable); 502 503 DtPushSubtable (Subtable); 504 ParentTable = DtPeekSubtable (); 505 if (*PFieldList) 506 { 507 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a, 508 &Subtable, TRUE); 509 if (ACPI_FAILURE (Status)) 510 { 511 return (Status); 512 } 513 if (Subtable) 514 { 515 DtInsertSubtable (ParentTable, Subtable); 516 } 517 } 518 DtPopSubtable (); 519 ParentTable = DtPeekSubtable (); 520 521 DescriptorCount--; 522 } 523 524 DtPopSubtable (); 525 ParentTable = DtPeekSubtable (); 526 } 527 528 return (Status); 529 } 530 531 532 /****************************************************************************** 533 * 534 * FUNCTION: DtCompileDbg2 535 * 536 * PARAMETERS: List - Current field list pointer 537 * 538 * RETURN: Status 539 * 540 * DESCRIPTION: Compile DBG2. 541 * 542 *****************************************************************************/ 543 544 ACPI_STATUS 545 DtCompileDbg2 ( 546 void **List) 547 { 548 ACPI_STATUS Status; 549 DT_SUBTABLE *Subtable; 550 DT_SUBTABLE *ParentTable; 551 DT_FIELD **PFieldList = (DT_FIELD **) List; 552 UINT32 SubtableCount; 553 ACPI_DBG2_HEADER *Dbg2Header; 554 ACPI_DBG2_DEVICE *DeviceInfo; 555 UINT16 CurrentOffset; 556 UINT32 i; 557 558 559 /* Main table */ 560 561 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable, TRUE); 562 if (ACPI_FAILURE (Status)) 563 { 564 return (Status); 565 } 566 567 ParentTable = DtPeekSubtable (); 568 DtInsertSubtable (ParentTable, Subtable); 569 570 /* Main table fields */ 571 572 Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer); 573 Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF ( 574 ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header); 575 576 SubtableCount = Dbg2Header->InfoCount; 577 DtPushSubtable (Subtable); 578 579 /* Process all Device Information subtables (Count = InfoCount) */ 580 581 while (*PFieldList && SubtableCount) 582 { 583 /* Subtable: Debug Device Information */ 584 585 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device, 586 &Subtable, TRUE); 587 if (ACPI_FAILURE (Status)) 588 { 589 return (Status); 590 } 591 592 DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer); 593 CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE); 594 595 ParentTable = DtPeekSubtable (); 596 DtInsertSubtable (ParentTable, Subtable); 597 DtPushSubtable (Subtable); 598 599 ParentTable = DtPeekSubtable (); 600 601 /* BaseAddressRegister GAS array (Required, size is RegisterCount) */ 602 603 DeviceInfo->BaseAddressOffset = CurrentOffset; 604 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++) 605 { 606 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr, 607 &Subtable, TRUE); 608 if (ACPI_FAILURE (Status)) 609 { 610 return (Status); 611 } 612 613 CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS); 614 DtInsertSubtable (ParentTable, Subtable); 615 } 616 617 /* AddressSize array (Required, size = RegisterCount) */ 618 619 DeviceInfo->AddressSizeOffset = CurrentOffset; 620 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++) 621 { 622 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size, 623 &Subtable, TRUE); 624 if (ACPI_FAILURE (Status)) 625 { 626 return (Status); 627 } 628 629 CurrentOffset += (UINT16) sizeof (UINT32); 630 DtInsertSubtable (ParentTable, Subtable); 631 } 632 633 /* NamespaceString device identifier (Required, size = NamePathLength) */ 634 635 DeviceInfo->NamepathOffset = CurrentOffset; 636 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name, 637 &Subtable, TRUE); 638 if (ACPI_FAILURE (Status)) 639 { 640 return (Status); 641 } 642 643 /* Update the device info header */ 644 645 DeviceInfo->NamepathLength = (UINT16) Subtable->Length; 646 CurrentOffset += (UINT16) DeviceInfo->NamepathLength; 647 DtInsertSubtable (ParentTable, Subtable); 648 649 /* OemData - Variable-length data (Optional, size = OemDataLength) */ 650 651 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData, 652 &Subtable, TRUE); 653 if (ACPI_FAILURE (Status)) 654 { 655 return (Status); 656 } 657 658 /* Update the device info header (zeros if no OEM data present) */ 659 660 DeviceInfo->OemDataOffset = 0; 661 DeviceInfo->OemDataLength = 0; 662 663 /* Optional subtable (OemData) */ 664 665 if (Subtable && Subtable->Length) 666 { 667 DeviceInfo->OemDataOffset = CurrentOffset; 668 DeviceInfo->OemDataLength = (UINT16) Subtable->Length; 669 670 DtInsertSubtable (ParentTable, Subtable); 671 } 672 673 SubtableCount--; 674 DtPopSubtable (); /* Get next Device Information subtable */ 675 } 676 677 DtPopSubtable (); 678 return (AE_OK); 679 } 680 681 682 /****************************************************************************** 683 * 684 * FUNCTION: DtCompileDmar 685 * 686 * PARAMETERS: List - Current field list pointer 687 * 688 * RETURN: Status 689 * 690 * DESCRIPTION: Compile DMAR. 691 * 692 *****************************************************************************/ 693 694 ACPI_STATUS 695 DtCompileDmar ( 696 void **List) 697 { 698 ACPI_STATUS Status; 699 DT_SUBTABLE *Subtable; 700 DT_SUBTABLE *ParentTable; 701 DT_FIELD **PFieldList = (DT_FIELD **) List; 702 DT_FIELD *SubtableStart; 703 ACPI_DMTABLE_INFO *InfoTable; 704 ACPI_DMAR_HEADER *DmarHeader; 705 ACPI_DMAR_DEVICE_SCOPE *DmarDeviceScope; 706 UINT32 DeviceScopeLength; 707 UINT32 PciPathLength; 708 709 710 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &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 while (*PFieldList) 721 { 722 /* DMAR Header */ 723 724 SubtableStart = *PFieldList; 725 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr, 726 &Subtable, TRUE); 727 if (ACPI_FAILURE (Status)) 728 { 729 return (Status); 730 } 731 732 ParentTable = DtPeekSubtable (); 733 DtInsertSubtable (ParentTable, Subtable); 734 DtPushSubtable (Subtable); 735 736 DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer); 737 738 switch (DmarHeader->Type) 739 { 740 case ACPI_DMAR_TYPE_HARDWARE_UNIT: 741 742 InfoTable = AcpiDmTableInfoDmar0; 743 break; 744 745 case ACPI_DMAR_TYPE_RESERVED_MEMORY: 746 747 InfoTable = AcpiDmTableInfoDmar1; 748 break; 749 750 case ACPI_DMAR_TYPE_ROOT_ATS: 751 752 InfoTable = AcpiDmTableInfoDmar2; 753 break; 754 755 case ACPI_DMAR_TYPE_HARDWARE_AFFINITY: 756 757 InfoTable = AcpiDmTableInfoDmar3; 758 break; 759 760 case ACPI_DMAR_TYPE_NAMESPACE: 761 762 InfoTable = AcpiDmTableInfoDmar4; 763 break; 764 765 default: 766 767 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR"); 768 return (AE_ERROR); 769 } 770 771 /* DMAR Subtable */ 772 773 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 774 if (ACPI_FAILURE (Status)) 775 { 776 return (Status); 777 } 778 779 ParentTable = DtPeekSubtable (); 780 DtInsertSubtable (ParentTable, Subtable); 781 782 /* 783 * Optional Device Scope subtables 784 */ 785 if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) || 786 (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE)) 787 { 788 /* These types do not support device scopes */ 789 790 DtPopSubtable (); 791 continue; 792 } 793 794 DtPushSubtable (Subtable); 795 DeviceScopeLength = DmarHeader->Length - Subtable->Length - 796 ParentTable->Length; 797 while (DeviceScopeLength) 798 { 799 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope, 800 &Subtable, FALSE); 801 if (Status == AE_NOT_FOUND) 802 { 803 break; 804 } 805 806 ParentTable = DtPeekSubtable (); 807 DtInsertSubtable (ParentTable, Subtable); 808 DtPushSubtable (Subtable); 809 810 DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer); 811 812 /* Optional PCI Paths */ 813 814 PciPathLength = DmarDeviceScope->Length - Subtable->Length; 815 while (PciPathLength) 816 { 817 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath, 818 &Subtable, FALSE); 819 if (Status == AE_NOT_FOUND) 820 { 821 DtPopSubtable (); 822 break; 823 } 824 825 ParentTable = DtPeekSubtable (); 826 DtInsertSubtable (ParentTable, Subtable); 827 PciPathLength -= Subtable->Length; 828 } 829 830 DtPopSubtable (); 831 DeviceScopeLength -= DmarDeviceScope->Length; 832 } 833 834 DtPopSubtable (); 835 DtPopSubtable (); 836 } 837 838 return (AE_OK); 839 } 840 841 842 /****************************************************************************** 843 * 844 * FUNCTION: DtCompileDrtm 845 * 846 * PARAMETERS: List - Current field list pointer 847 * 848 * RETURN: Status 849 * 850 * DESCRIPTION: Compile DRTM. 851 * 852 *****************************************************************************/ 853 854 ACPI_STATUS 855 DtCompileDrtm ( 856 void **List) 857 { 858 ACPI_STATUS Status; 859 DT_SUBTABLE *Subtable; 860 DT_SUBTABLE *ParentTable; 861 DT_FIELD **PFieldList = (DT_FIELD **) List; 862 UINT32 Count; 863 /* ACPI_TABLE_DRTM *Drtm; */ 864 ACPI_DRTM_VTABLE_LIST *DrtmVtl; 865 ACPI_DRTM_RESOURCE_LIST *DrtmRl; 866 /* ACPI_DRTM_DPS_ID *DrtmDps; */ 867 868 869 ParentTable = DtPeekSubtable (); 870 871 /* Compile DRTM header */ 872 873 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm, 874 &Subtable, TRUE); 875 if (ACPI_FAILURE (Status)) 876 { 877 return (Status); 878 } 879 DtInsertSubtable (ParentTable, Subtable); 880 881 /* 882 * Using ACPI_SUB_PTR, We needn't define a seperate structure. Care 883 * should be taken to avoid accessing ACPI_TABLE_HADER fields. 884 */ 885 #if 0 886 Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM, 887 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER)); 888 #endif 889 /* Compile VTL */ 890 891 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0, 892 &Subtable, TRUE); 893 if (ACPI_FAILURE (Status)) 894 { 895 return (Status); 896 } 897 DtInsertSubtable (ParentTable, Subtable); 898 DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer); 899 900 DtPushSubtable (Subtable); 901 ParentTable = DtPeekSubtable (); 902 Count = 0; 903 while (*PFieldList) 904 { 905 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a, 906 &Subtable, TRUE); 907 if (ACPI_FAILURE (Status)) 908 { 909 return (Status); 910 } 911 if (!Subtable) 912 { 913 break; 914 } 915 DtInsertSubtable (ParentTable, Subtable); 916 Count++; 917 } 918 DrtmVtl->ValidatedTableCount = Count; 919 DtPopSubtable (); 920 ParentTable = DtPeekSubtable (); 921 922 /* Compile RL */ 923 924 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1, 925 &Subtable, TRUE); 926 if (ACPI_FAILURE (Status)) 927 { 928 return (Status); 929 } 930 DtInsertSubtable (ParentTable, Subtable); 931 DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer); 932 933 DtPushSubtable (Subtable); 934 ParentTable = DtPeekSubtable (); 935 Count = 0; 936 while (*PFieldList) 937 { 938 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a, 939 &Subtable, TRUE); 940 if (ACPI_FAILURE (Status)) 941 { 942 return (Status); 943 } 944 if (!Subtable) 945 { 946 break; 947 } 948 DtInsertSubtable (ParentTable, Subtable); 949 Count++; 950 } 951 DrtmRl->ResourceCount = Count; 952 DtPopSubtable (); 953 ParentTable = DtPeekSubtable (); 954 955 /* Compile DPS */ 956 957 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2, 958 &Subtable, TRUE); 959 if (ACPI_FAILURE (Status)) 960 { 961 return (Status); 962 } 963 DtInsertSubtable (ParentTable, Subtable); 964 /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/ 965 966 967 return (AE_OK); 968 } 969 970 971 /****************************************************************************** 972 * 973 * FUNCTION: DtCompileEinj 974 * 975 * PARAMETERS: List - Current field list pointer 976 * 977 * RETURN: Status 978 * 979 * DESCRIPTION: Compile EINJ. 980 * 981 *****************************************************************************/ 982 983 ACPI_STATUS 984 DtCompileEinj ( 985 void **List) 986 { 987 ACPI_STATUS Status; 988 989 990 Status = DtCompileTwoSubtables (List, 991 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0); 992 return (Status); 993 } 994 995 996 /****************************************************************************** 997 * 998 * FUNCTION: DtCompileErst 999 * 1000 * PARAMETERS: List - Current field list pointer 1001 * 1002 * RETURN: Status 1003 * 1004 * DESCRIPTION: Compile ERST. 1005 * 1006 *****************************************************************************/ 1007 1008 ACPI_STATUS 1009 DtCompileErst ( 1010 void **List) 1011 { 1012 ACPI_STATUS Status; 1013 1014 1015 Status = DtCompileTwoSubtables (List, 1016 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0); 1017 return (Status); 1018 } 1019 1020 1021 /****************************************************************************** 1022 * 1023 * FUNCTION: DtCompileFadt 1024 * 1025 * PARAMETERS: List - Current field list pointer 1026 * 1027 * RETURN: Status 1028 * 1029 * DESCRIPTION: Compile FADT. 1030 * 1031 *****************************************************************************/ 1032 1033 ACPI_STATUS 1034 DtCompileFadt ( 1035 void **List) 1036 { 1037 ACPI_STATUS Status; 1038 DT_SUBTABLE *Subtable; 1039 DT_SUBTABLE *ParentTable; 1040 DT_FIELD **PFieldList = (DT_FIELD **) List; 1041 ACPI_TABLE_HEADER *Table; 1042 UINT8 Revision; 1043 1044 1045 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt1, 1046 &Subtable, TRUE); 1047 if (ACPI_FAILURE (Status)) 1048 { 1049 return (Status); 1050 } 1051 1052 ParentTable = DtPeekSubtable (); 1053 DtInsertSubtable (ParentTable, Subtable); 1054 1055 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 1056 Revision = Table->Revision; 1057 1058 if (Revision == 2) 1059 { 1060 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt2, 1061 &Subtable, TRUE); 1062 if (ACPI_FAILURE (Status)) 1063 { 1064 return (Status); 1065 } 1066 1067 DtInsertSubtable (ParentTable, Subtable); 1068 } 1069 else if (Revision >= 2) 1070 { 1071 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt3, 1072 &Subtable, TRUE); 1073 if (ACPI_FAILURE (Status)) 1074 { 1075 return (Status); 1076 } 1077 1078 DtInsertSubtable (ParentTable, Subtable); 1079 1080 if (Revision >= 5) 1081 { 1082 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt5, 1083 &Subtable, TRUE); 1084 if (ACPI_FAILURE (Status)) 1085 { 1086 return (Status); 1087 } 1088 1089 DtInsertSubtable (ParentTable, Subtable); 1090 } 1091 1092 if (Revision >= 6) 1093 { 1094 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt6, 1095 &Subtable, TRUE); 1096 if (ACPI_FAILURE (Status)) 1097 { 1098 return (Status); 1099 } 1100 1101 DtInsertSubtable (ParentTable, Subtable); 1102 } 1103 } 1104 1105 return (AE_OK); 1106 } 1107 1108 /****************************************************************************** 1109 * 1110 * FUNCTION: DtCompileGtdt 1111 * 1112 * PARAMETERS: List - Current field list pointer 1113 * 1114 * RETURN: Status 1115 * 1116 * DESCRIPTION: Compile GTDT. 1117 * 1118 *****************************************************************************/ 1119 1120 ACPI_STATUS 1121 DtCompileGtdt ( 1122 void **List) 1123 { 1124 ACPI_STATUS Status; 1125 DT_SUBTABLE *Subtable; 1126 DT_SUBTABLE *ParentTable; 1127 DT_FIELD **PFieldList = (DT_FIELD **) List; 1128 DT_FIELD *SubtableStart; 1129 ACPI_SUBTABLE_HEADER *GtdtHeader; 1130 ACPI_DMTABLE_INFO *InfoTable; 1131 UINT32 GtCount; 1132 1133 1134 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt, 1135 &Subtable, TRUE); 1136 if (ACPI_FAILURE (Status)) 1137 { 1138 return (Status); 1139 } 1140 1141 ParentTable = DtPeekSubtable (); 1142 DtInsertSubtable (ParentTable, Subtable); 1143 1144 while (*PFieldList) 1145 { 1146 SubtableStart = *PFieldList; 1147 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr, 1148 &Subtable, TRUE); 1149 if (ACPI_FAILURE (Status)) 1150 { 1151 return (Status); 1152 } 1153 1154 ParentTable = DtPeekSubtable (); 1155 DtInsertSubtable (ParentTable, Subtable); 1156 DtPushSubtable (Subtable); 1157 1158 GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1159 1160 switch (GtdtHeader->Type) 1161 { 1162 case ACPI_GTDT_TYPE_TIMER_BLOCK: 1163 1164 InfoTable = AcpiDmTableInfoGtdt0; 1165 break; 1166 1167 case ACPI_GTDT_TYPE_WATCHDOG: 1168 1169 InfoTable = AcpiDmTableInfoGtdt1; 1170 break; 1171 1172 default: 1173 1174 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT"); 1175 return (AE_ERROR); 1176 } 1177 1178 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1179 if (ACPI_FAILURE (Status)) 1180 { 1181 return (Status); 1182 } 1183 1184 ParentTable = DtPeekSubtable (); 1185 DtInsertSubtable (ParentTable, Subtable); 1186 1187 /* 1188 * Additional GT block subtable data 1189 */ 1190 1191 switch (GtdtHeader->Type) 1192 { 1193 case ACPI_GTDT_TYPE_TIMER_BLOCK: 1194 1195 DtPushSubtable (Subtable); 1196 ParentTable = DtPeekSubtable (); 1197 1198 GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK, 1199 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount; 1200 while (GtCount) 1201 { 1202 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a, 1203 &Subtable, TRUE); 1204 if (ACPI_FAILURE (Status)) 1205 { 1206 return (Status); 1207 } 1208 1209 1210 DtInsertSubtable (ParentTable, Subtable); 1211 GtCount--; 1212 } 1213 DtPopSubtable (); 1214 break; 1215 1216 default: 1217 1218 break; 1219 } 1220 1221 DtPopSubtable (); 1222 } 1223 1224 return (AE_OK); 1225 } 1226 1227 1228 /****************************************************************************** 1229 * 1230 * FUNCTION: DtCompileFpdt 1231 * 1232 * PARAMETERS: List - Current field list pointer 1233 * 1234 * RETURN: Status 1235 * 1236 * DESCRIPTION: Compile FPDT. 1237 * 1238 *****************************************************************************/ 1239 1240 ACPI_STATUS 1241 DtCompileFpdt ( 1242 void **List) 1243 { 1244 ACPI_STATUS Status; 1245 ACPI_FPDT_HEADER *FpdtHeader; 1246 DT_SUBTABLE *Subtable; 1247 DT_SUBTABLE *ParentTable; 1248 ACPI_DMTABLE_INFO *InfoTable; 1249 DT_FIELD **PFieldList = (DT_FIELD **) List; 1250 DT_FIELD *SubtableStart; 1251 1252 1253 while (*PFieldList) 1254 { 1255 SubtableStart = *PFieldList; 1256 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr, 1257 &Subtable, TRUE); 1258 if (ACPI_FAILURE (Status)) 1259 { 1260 return (Status); 1261 } 1262 1263 ParentTable = DtPeekSubtable (); 1264 DtInsertSubtable (ParentTable, Subtable); 1265 DtPushSubtable (Subtable); 1266 1267 FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer); 1268 1269 switch (FpdtHeader->Type) 1270 { 1271 case ACPI_FPDT_TYPE_BOOT: 1272 1273 InfoTable = AcpiDmTableInfoFpdt0; 1274 break; 1275 1276 case ACPI_FPDT_TYPE_S3PERF: 1277 1278 InfoTable = AcpiDmTableInfoFpdt1; 1279 break; 1280 1281 default: 1282 1283 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT"); 1284 return (AE_ERROR); 1285 break; 1286 } 1287 1288 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1289 if (ACPI_FAILURE (Status)) 1290 { 1291 return (Status); 1292 } 1293 1294 ParentTable = DtPeekSubtable (); 1295 DtInsertSubtable (ParentTable, Subtable); 1296 DtPopSubtable (); 1297 } 1298 1299 return (AE_OK); 1300 } 1301 1302 1303 /****************************************************************************** 1304 * 1305 * FUNCTION: DtCompileHest 1306 * 1307 * PARAMETERS: List - Current field list pointer 1308 * 1309 * RETURN: Status 1310 * 1311 * DESCRIPTION: Compile HEST. 1312 * 1313 *****************************************************************************/ 1314 1315 ACPI_STATUS 1316 DtCompileHest ( 1317 void **List) 1318 { 1319 ACPI_STATUS Status; 1320 DT_SUBTABLE *Subtable; 1321 DT_SUBTABLE *ParentTable; 1322 DT_FIELD **PFieldList = (DT_FIELD **) List; 1323 DT_FIELD *SubtableStart; 1324 ACPI_DMTABLE_INFO *InfoTable; 1325 UINT16 Type; 1326 UINT32 BankCount; 1327 1328 1329 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest, 1330 &Subtable, TRUE); 1331 if (ACPI_FAILURE (Status)) 1332 { 1333 return (Status); 1334 } 1335 1336 ParentTable = DtPeekSubtable (); 1337 DtInsertSubtable (ParentTable, Subtable); 1338 1339 while (*PFieldList) 1340 { 1341 /* Get subtable type */ 1342 1343 SubtableStart = *PFieldList; 1344 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0); 1345 1346 switch (Type) 1347 { 1348 case ACPI_HEST_TYPE_IA32_CHECK: 1349 1350 InfoTable = AcpiDmTableInfoHest0; 1351 break; 1352 1353 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 1354 1355 InfoTable = AcpiDmTableInfoHest1; 1356 break; 1357 1358 case ACPI_HEST_TYPE_IA32_NMI: 1359 1360 InfoTable = AcpiDmTableInfoHest2; 1361 break; 1362 1363 case ACPI_HEST_TYPE_AER_ROOT_PORT: 1364 1365 InfoTable = AcpiDmTableInfoHest6; 1366 break; 1367 1368 case ACPI_HEST_TYPE_AER_ENDPOINT: 1369 1370 InfoTable = AcpiDmTableInfoHest7; 1371 break; 1372 1373 case ACPI_HEST_TYPE_AER_BRIDGE: 1374 1375 InfoTable = AcpiDmTableInfoHest8; 1376 break; 1377 1378 case ACPI_HEST_TYPE_GENERIC_ERROR: 1379 1380 InfoTable = AcpiDmTableInfoHest9; 1381 break; 1382 1383 default: 1384 1385 /* Cannot continue on unknown type */ 1386 1387 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST"); 1388 return (AE_ERROR); 1389 } 1390 1391 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1392 if (ACPI_FAILURE (Status)) 1393 { 1394 return (Status); 1395 } 1396 1397 DtInsertSubtable (ParentTable, Subtable); 1398 1399 /* 1400 * Additional subtable data - IA32 Error Bank(s) 1401 */ 1402 BankCount = 0; 1403 switch (Type) 1404 { 1405 case ACPI_HEST_TYPE_IA32_CHECK: 1406 1407 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK, 1408 Subtable->Buffer))->NumHardwareBanks; 1409 break; 1410 1411 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: 1412 1413 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED, 1414 Subtable->Buffer))->NumHardwareBanks; 1415 break; 1416 1417 default: 1418 1419 break; 1420 } 1421 1422 while (BankCount) 1423 { 1424 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank, 1425 &Subtable, TRUE); 1426 if (ACPI_FAILURE (Status)) 1427 { 1428 return (Status); 1429 } 1430 1431 DtInsertSubtable (ParentTable, Subtable); 1432 BankCount--; 1433 } 1434 } 1435 1436 return (AE_OK); 1437 } 1438 1439 1440 /****************************************************************************** 1441 * 1442 * FUNCTION: DtCompileIort 1443 * 1444 * PARAMETERS: List - Current field list pointer 1445 * 1446 * RETURN: Status 1447 * 1448 * DESCRIPTION: Compile IORT. 1449 * 1450 *****************************************************************************/ 1451 1452 ACPI_STATUS 1453 DtCompileIort ( 1454 void **List) 1455 { 1456 ACPI_STATUS Status; 1457 DT_SUBTABLE *Subtable; 1458 DT_SUBTABLE *ParentTable; 1459 DT_FIELD **PFieldList = (DT_FIELD **) List; 1460 DT_FIELD *SubtableStart; 1461 ACPI_TABLE_IORT *Iort; 1462 ACPI_IORT_NODE *IortNode; 1463 ACPI_IORT_ITS_GROUP *IortItsGroup; 1464 ACPI_IORT_SMMU *IortSmmu; 1465 UINT32 NodeNumber; 1466 UINT32 NodeLength; 1467 UINT32 IdMappingNumber; 1468 UINT32 ItsNumber; 1469 UINT32 ContextIrptNumber; 1470 UINT32 PmuIrptNumber; 1471 UINT32 PaddingLength; 1472 1473 1474 ParentTable = DtPeekSubtable (); 1475 1476 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort, 1477 &Subtable, TRUE); 1478 if (ACPI_FAILURE (Status)) 1479 { 1480 return (Status); 1481 } 1482 DtInsertSubtable (ParentTable, Subtable); 1483 1484 /* 1485 * Using ACPI_SUB_PTR, We needn't define a seperate structure. Care 1486 * should be taken to avoid accessing ACPI_TABLE_HADER fields. 1487 */ 1488 Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT, 1489 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER)); 1490 1491 /* 1492 * OptionalPadding - Variable-length data 1493 * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT)) 1494 * Optionally allows the generic data types to be used for filling 1495 * this field. 1496 */ 1497 Iort->NodeOffset = sizeof (ACPI_TABLE_IORT); 1498 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad, 1499 &Subtable, TRUE); 1500 if (ACPI_FAILURE (Status)) 1501 { 1502 return (Status); 1503 } 1504 if (Subtable) 1505 { 1506 DtInsertSubtable (ParentTable, Subtable); 1507 Iort->NodeOffset += Subtable->Length; 1508 } 1509 else 1510 { 1511 Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList), 1512 AcpiDmTableInfoIortHdr[0].Name, &PaddingLength); 1513 if (ACPI_FAILURE (Status)) 1514 { 1515 return (Status); 1516 } 1517 Iort->NodeOffset += PaddingLength; 1518 } 1519 1520 NodeNumber = 0; 1521 while (*PFieldList) 1522 { 1523 SubtableStart = *PFieldList; 1524 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr, 1525 &Subtable, TRUE); 1526 if (ACPI_FAILURE (Status)) 1527 { 1528 return (Status); 1529 } 1530 DtInsertSubtable (ParentTable, Subtable); 1531 IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer); 1532 NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData); 1533 1534 DtPushSubtable (Subtable); 1535 ParentTable = DtPeekSubtable (); 1536 1537 switch (IortNode->Type) 1538 { 1539 case ACPI_IORT_NODE_ITS_GROUP: 1540 1541 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0, 1542 &Subtable, TRUE); 1543 if (ACPI_FAILURE (Status)) 1544 { 1545 return (Status); 1546 } 1547 DtInsertSubtable (ParentTable, Subtable); 1548 IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer); 1549 NodeLength += Subtable->Length; 1550 1551 ItsNumber = 0; 1552 while (*PFieldList) 1553 { 1554 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a, 1555 &Subtable, TRUE); 1556 if (ACPI_FAILURE (Status)) 1557 { 1558 return (Status); 1559 } 1560 if (!Subtable) 1561 { 1562 break; 1563 } 1564 DtInsertSubtable (ParentTable, Subtable); 1565 NodeLength += Subtable->Length; 1566 ItsNumber++; 1567 } 1568 1569 IortItsGroup->ItsCount = ItsNumber; 1570 break; 1571 1572 case ACPI_IORT_NODE_NAMED_COMPONENT: 1573 1574 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1, 1575 &Subtable, TRUE); 1576 if (ACPI_FAILURE (Status)) 1577 { 1578 return (Status); 1579 } 1580 DtInsertSubtable (ParentTable, Subtable); 1581 NodeLength += Subtable->Length; 1582 1583 /* 1584 * Padding - Variable-length data 1585 * Optionally allows the offset of the ID mappings to be used 1586 * for filling this field. 1587 */ 1588 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a, 1589 &Subtable, TRUE); 1590 if (ACPI_FAILURE (Status)) 1591 { 1592 return (Status); 1593 } 1594 if (Subtable) 1595 { 1596 DtInsertSubtable (ParentTable, Subtable); 1597 NodeLength += Subtable->Length; 1598 } 1599 else 1600 { 1601 if (NodeLength > IortNode->MappingOffset) 1602 { 1603 return (AE_BAD_DATA); 1604 } 1605 if (NodeLength < IortNode->MappingOffset) 1606 { 1607 Status = DtCompilePadding ( 1608 IortNode->MappingOffset - NodeLength, 1609 &Subtable); 1610 if (ACPI_FAILURE (Status)) 1611 { 1612 return (Status); 1613 } 1614 DtInsertSubtable (ParentTable, Subtable); 1615 NodeLength = IortNode->MappingOffset; 1616 } 1617 } 1618 break; 1619 1620 case ACPI_IORT_NODE_PCI_ROOT_COMPLEX: 1621 1622 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2, 1623 &Subtable, TRUE); 1624 if (ACPI_FAILURE (Status)) 1625 { 1626 return (Status); 1627 } 1628 DtInsertSubtable (ParentTable, Subtable); 1629 NodeLength += Subtable->Length; 1630 break; 1631 1632 case ACPI_IORT_NODE_SMMU: 1633 1634 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3, 1635 &Subtable, TRUE); 1636 if (ACPI_FAILURE (Status)) 1637 { 1638 return (Status); 1639 } 1640 DtInsertSubtable (ParentTable, Subtable); 1641 IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer); 1642 NodeLength += Subtable->Length; 1643 1644 /* Compile global interrupt array */ 1645 1646 IortSmmu->GlobalInterruptOffset = NodeLength; 1647 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a, 1648 &Subtable, TRUE); 1649 if (ACPI_FAILURE (Status)) 1650 { 1651 return (Status); 1652 } 1653 DtInsertSubtable (ParentTable, Subtable); 1654 NodeLength += Subtable->Length; 1655 1656 /* Compile context interrupt array */ 1657 1658 ContextIrptNumber = 0; 1659 IortSmmu->ContextInterruptOffset = NodeLength; 1660 while (*PFieldList) 1661 { 1662 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b, 1663 &Subtable, TRUE); 1664 if (ACPI_FAILURE (Status)) 1665 { 1666 return (Status); 1667 } 1668 if (!Subtable) 1669 { 1670 break; 1671 } 1672 DtInsertSubtable (ParentTable, Subtable); 1673 NodeLength += Subtable->Length; 1674 ContextIrptNumber++; 1675 } 1676 IortSmmu->ContextInterruptCount = ContextIrptNumber; 1677 1678 /* Compile PMU interrupt array */ 1679 1680 PmuIrptNumber = 0; 1681 IortSmmu->PmuInterruptOffset = NodeLength; 1682 while (*PFieldList) 1683 { 1684 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c, 1685 &Subtable, TRUE); 1686 if (ACPI_FAILURE (Status)) 1687 { 1688 return (Status); 1689 } 1690 if (!Subtable) 1691 { 1692 break; 1693 } 1694 DtInsertSubtable (ParentTable, Subtable); 1695 NodeLength += Subtable->Length; 1696 PmuIrptNumber++; 1697 } 1698 IortSmmu->PmuInterruptCount = PmuIrptNumber; 1699 break; 1700 1701 default: 1702 1703 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT"); 1704 return (AE_ERROR); 1705 } 1706 1707 /* Compile Array of ID mappings */ 1708 1709 IortNode->MappingOffset = NodeLength; 1710 IdMappingNumber = 0; 1711 while (*PFieldList) 1712 { 1713 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap, 1714 &Subtable, TRUE); 1715 if (ACPI_FAILURE (Status)) 1716 { 1717 return (Status); 1718 } 1719 if (!Subtable) 1720 { 1721 break; 1722 } 1723 DtInsertSubtable (ParentTable, Subtable); 1724 NodeLength += sizeof (ACPI_IORT_ID_MAPPING); 1725 IdMappingNumber++; 1726 } 1727 IortNode->MappingCount = IdMappingNumber; 1728 1729 /* 1730 * Node length can be determined by DT_LENGTH option 1731 * IortNode->Length = NodeLength; 1732 */ 1733 DtPopSubtable (); 1734 ParentTable = DtPeekSubtable (); 1735 NodeNumber++; 1736 } 1737 Iort->NodeCount = NodeNumber; 1738 1739 return (AE_OK); 1740 } 1741 1742 1743 /****************************************************************************** 1744 * 1745 * FUNCTION: DtCompileIvrs 1746 * 1747 * PARAMETERS: List - Current field list pointer 1748 * 1749 * RETURN: Status 1750 * 1751 * DESCRIPTION: Compile IVRS. 1752 * 1753 *****************************************************************************/ 1754 1755 ACPI_STATUS 1756 DtCompileIvrs ( 1757 void **List) 1758 { 1759 ACPI_STATUS Status; 1760 DT_SUBTABLE *Subtable; 1761 DT_SUBTABLE *ParentTable; 1762 DT_FIELD **PFieldList = (DT_FIELD **) List; 1763 DT_FIELD *SubtableStart; 1764 ACPI_DMTABLE_INFO *InfoTable; 1765 ACPI_IVRS_HEADER *IvrsHeader; 1766 UINT8 EntryType; 1767 1768 1769 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs, 1770 &Subtable, TRUE); 1771 if (ACPI_FAILURE (Status)) 1772 { 1773 return (Status); 1774 } 1775 1776 ParentTable = DtPeekSubtable (); 1777 DtInsertSubtable (ParentTable, Subtable); 1778 1779 while (*PFieldList) 1780 { 1781 SubtableStart = *PFieldList; 1782 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr, 1783 &Subtable, TRUE); 1784 if (ACPI_FAILURE (Status)) 1785 { 1786 return (Status); 1787 } 1788 1789 ParentTable = DtPeekSubtable (); 1790 DtInsertSubtable (ParentTable, Subtable); 1791 DtPushSubtable (Subtable); 1792 1793 IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer); 1794 1795 switch (IvrsHeader->Type) 1796 { 1797 case ACPI_IVRS_TYPE_HARDWARE: 1798 1799 InfoTable = AcpiDmTableInfoIvrs0; 1800 break; 1801 1802 case ACPI_IVRS_TYPE_MEMORY1: 1803 case ACPI_IVRS_TYPE_MEMORY2: 1804 case ACPI_IVRS_TYPE_MEMORY3: 1805 1806 InfoTable = AcpiDmTableInfoIvrs1; 1807 break; 1808 1809 default: 1810 1811 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS"); 1812 return (AE_ERROR); 1813 } 1814 1815 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1816 if (ACPI_FAILURE (Status)) 1817 { 1818 return (Status); 1819 } 1820 1821 ParentTable = DtPeekSubtable (); 1822 DtInsertSubtable (ParentTable, Subtable); 1823 1824 if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE) 1825 { 1826 while (*PFieldList && 1827 !strcmp ((*PFieldList)->Name, "Entry Type")) 1828 { 1829 SubtableStart = *PFieldList; 1830 DtCompileInteger (&EntryType, *PFieldList, 1, 0); 1831 1832 switch (EntryType) 1833 { 1834 /* 4-byte device entries */ 1835 1836 case ACPI_IVRS_TYPE_PAD4: 1837 case ACPI_IVRS_TYPE_ALL: 1838 case ACPI_IVRS_TYPE_SELECT: 1839 case ACPI_IVRS_TYPE_START: 1840 case ACPI_IVRS_TYPE_END: 1841 1842 InfoTable = AcpiDmTableInfoIvrs4; 1843 break; 1844 1845 /* 8-byte entries, type A */ 1846 1847 case ACPI_IVRS_TYPE_ALIAS_SELECT: 1848 case ACPI_IVRS_TYPE_ALIAS_START: 1849 1850 InfoTable = AcpiDmTableInfoIvrs8a; 1851 break; 1852 1853 /* 8-byte entries, type B */ 1854 1855 case ACPI_IVRS_TYPE_PAD8: 1856 case ACPI_IVRS_TYPE_EXT_SELECT: 1857 case ACPI_IVRS_TYPE_EXT_START: 1858 1859 InfoTable = AcpiDmTableInfoIvrs8b; 1860 break; 1861 1862 /* 8-byte entries, type C */ 1863 1864 case ACPI_IVRS_TYPE_SPECIAL: 1865 1866 InfoTable = AcpiDmTableInfoIvrs8c; 1867 break; 1868 1869 default: 1870 1871 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, 1872 "IVRS Device Entry"); 1873 return (AE_ERROR); 1874 } 1875 1876 Status = DtCompileTable (PFieldList, InfoTable, 1877 &Subtable, TRUE); 1878 if (ACPI_FAILURE (Status)) 1879 { 1880 return (Status); 1881 } 1882 1883 DtInsertSubtable (ParentTable, Subtable); 1884 } 1885 } 1886 1887 DtPopSubtable (); 1888 } 1889 1890 return (AE_OK); 1891 } 1892 1893 1894 /****************************************************************************** 1895 * 1896 * FUNCTION: DtCompileLpit 1897 * 1898 * PARAMETERS: List - Current field list pointer 1899 * 1900 * RETURN: Status 1901 * 1902 * DESCRIPTION: Compile LPIT. 1903 * 1904 *****************************************************************************/ 1905 1906 ACPI_STATUS 1907 DtCompileLpit ( 1908 void **List) 1909 { 1910 ACPI_STATUS Status; 1911 DT_SUBTABLE *Subtable; 1912 DT_SUBTABLE *ParentTable; 1913 DT_FIELD **PFieldList = (DT_FIELD **) List; 1914 DT_FIELD *SubtableStart; 1915 ACPI_DMTABLE_INFO *InfoTable; 1916 ACPI_LPIT_HEADER *LpitHeader; 1917 1918 1919 /* Note: Main table consists only of the standard ACPI table header */ 1920 1921 while (*PFieldList) 1922 { 1923 SubtableStart = *PFieldList; 1924 1925 /* LPIT Subtable header */ 1926 1927 Status = DtCompileTable (PFieldList, AcpiDmTableInfoLpitHdr, 1928 &Subtable, TRUE); 1929 if (ACPI_FAILURE (Status)) 1930 { 1931 return (Status); 1932 } 1933 1934 ParentTable = DtPeekSubtable (); 1935 DtInsertSubtable (ParentTable, Subtable); 1936 DtPushSubtable (Subtable); 1937 1938 LpitHeader = ACPI_CAST_PTR (ACPI_LPIT_HEADER, Subtable->Buffer); 1939 1940 switch (LpitHeader->Type) 1941 { 1942 case ACPI_LPIT_TYPE_NATIVE_CSTATE: 1943 1944 InfoTable = AcpiDmTableInfoLpit0; 1945 break; 1946 1947 default: 1948 1949 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "LPIT"); 1950 return (AE_ERROR); 1951 } 1952 1953 /* LPIT Subtable */ 1954 1955 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1956 if (ACPI_FAILURE (Status)) 1957 { 1958 return (Status); 1959 } 1960 1961 ParentTable = DtPeekSubtable (); 1962 DtInsertSubtable (ParentTable, Subtable); 1963 DtPopSubtable (); 1964 } 1965 1966 return (AE_OK); 1967 } 1968 1969 1970 /****************************************************************************** 1971 * 1972 * FUNCTION: DtCompileMadt 1973 * 1974 * PARAMETERS: List - Current field list pointer 1975 * 1976 * RETURN: Status 1977 * 1978 * DESCRIPTION: Compile MADT. 1979 * 1980 *****************************************************************************/ 1981 1982 ACPI_STATUS 1983 DtCompileMadt ( 1984 void **List) 1985 { 1986 ACPI_STATUS Status; 1987 DT_SUBTABLE *Subtable; 1988 DT_SUBTABLE *ParentTable; 1989 DT_FIELD **PFieldList = (DT_FIELD **) List; 1990 DT_FIELD *SubtableStart; 1991 ACPI_SUBTABLE_HEADER *MadtHeader; 1992 ACPI_DMTABLE_INFO *InfoTable; 1993 1994 1995 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt, 1996 &Subtable, TRUE); 1997 if (ACPI_FAILURE (Status)) 1998 { 1999 return (Status); 2000 } 2001 2002 ParentTable = DtPeekSubtable (); 2003 DtInsertSubtable (ParentTable, Subtable); 2004 2005 while (*PFieldList) 2006 { 2007 SubtableStart = *PFieldList; 2008 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr, 2009 &Subtable, TRUE); 2010 if (ACPI_FAILURE (Status)) 2011 { 2012 return (Status); 2013 } 2014 2015 ParentTable = DtPeekSubtable (); 2016 DtInsertSubtable (ParentTable, Subtable); 2017 DtPushSubtable (Subtable); 2018 2019 MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 2020 2021 switch (MadtHeader->Type) 2022 { 2023 case ACPI_MADT_TYPE_LOCAL_APIC: 2024 2025 InfoTable = AcpiDmTableInfoMadt0; 2026 break; 2027 2028 case ACPI_MADT_TYPE_IO_APIC: 2029 2030 InfoTable = AcpiDmTableInfoMadt1; 2031 break; 2032 2033 case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: 2034 2035 InfoTable = AcpiDmTableInfoMadt2; 2036 break; 2037 2038 case ACPI_MADT_TYPE_NMI_SOURCE: 2039 2040 InfoTable = AcpiDmTableInfoMadt3; 2041 break; 2042 2043 case ACPI_MADT_TYPE_LOCAL_APIC_NMI: 2044 2045 InfoTable = AcpiDmTableInfoMadt4; 2046 break; 2047 2048 case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: 2049 2050 InfoTable = AcpiDmTableInfoMadt5; 2051 break; 2052 2053 case ACPI_MADT_TYPE_IO_SAPIC: 2054 2055 InfoTable = AcpiDmTableInfoMadt6; 2056 break; 2057 2058 case ACPI_MADT_TYPE_LOCAL_SAPIC: 2059 2060 InfoTable = AcpiDmTableInfoMadt7; 2061 break; 2062 2063 case ACPI_MADT_TYPE_INTERRUPT_SOURCE: 2064 2065 InfoTable = AcpiDmTableInfoMadt8; 2066 break; 2067 2068 case ACPI_MADT_TYPE_LOCAL_X2APIC: 2069 2070 InfoTable = AcpiDmTableInfoMadt9; 2071 break; 2072 2073 case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI: 2074 2075 InfoTable = AcpiDmTableInfoMadt10; 2076 break; 2077 2078 case ACPI_MADT_TYPE_GENERIC_INTERRUPT: 2079 2080 InfoTable = AcpiDmTableInfoMadt11; 2081 break; 2082 2083 case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR: 2084 2085 InfoTable = AcpiDmTableInfoMadt12; 2086 break; 2087 2088 case ACPI_MADT_TYPE_GENERIC_MSI_FRAME: 2089 2090 InfoTable = AcpiDmTableInfoMadt13; 2091 break; 2092 2093 case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR: 2094 2095 InfoTable = AcpiDmTableInfoMadt14; 2096 break; 2097 2098 case ACPI_MADT_TYPE_GENERIC_TRANSLATOR: 2099 2100 InfoTable = AcpiDmTableInfoMadt15; 2101 break; 2102 2103 default: 2104 2105 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT"); 2106 return (AE_ERROR); 2107 } 2108 2109 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 2110 if (ACPI_FAILURE (Status)) 2111 { 2112 return (Status); 2113 } 2114 2115 ParentTable = DtPeekSubtable (); 2116 DtInsertSubtable (ParentTable, Subtable); 2117 DtPopSubtable (); 2118 } 2119 2120 return (AE_OK); 2121 } 2122 2123 2124 /****************************************************************************** 2125 * 2126 * FUNCTION: DtCompileMcfg 2127 * 2128 * PARAMETERS: List - Current field list pointer 2129 * 2130 * RETURN: Status 2131 * 2132 * DESCRIPTION: Compile MCFG. 2133 * 2134 *****************************************************************************/ 2135 2136 ACPI_STATUS 2137 DtCompileMcfg ( 2138 void **List) 2139 { 2140 ACPI_STATUS Status; 2141 2142 2143 Status = DtCompileTwoSubtables (List, 2144 AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0); 2145 return (Status); 2146 } 2147 2148 2149 /****************************************************************************** 2150 * 2151 * FUNCTION: DtCompileMpst 2152 * 2153 * PARAMETERS: List - Current field list pointer 2154 * 2155 * RETURN: Status 2156 * 2157 * DESCRIPTION: Compile MPST. 2158 * 2159 *****************************************************************************/ 2160 2161 ACPI_STATUS 2162 DtCompileMpst ( 2163 void **List) 2164 { 2165 ACPI_STATUS Status; 2166 DT_SUBTABLE *Subtable; 2167 DT_SUBTABLE *ParentTable; 2168 DT_FIELD **PFieldList = (DT_FIELD **) List; 2169 ACPI_MPST_CHANNEL *MpstChannelInfo; 2170 ACPI_MPST_POWER_NODE *MpstPowerNode; 2171 ACPI_MPST_DATA_HDR *MpstDataHeader; 2172 UINT16 SubtableCount; 2173 UINT32 PowerStateCount; 2174 UINT32 ComponentCount; 2175 2176 2177 /* Main table */ 2178 2179 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable, TRUE); 2180 if (ACPI_FAILURE (Status)) 2181 { 2182 return (Status); 2183 } 2184 2185 ParentTable = DtPeekSubtable (); 2186 DtInsertSubtable (ParentTable, Subtable); 2187 DtPushSubtable (Subtable); 2188 2189 MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer); 2190 SubtableCount = MpstChannelInfo->PowerNodeCount; 2191 2192 while (*PFieldList && SubtableCount) 2193 { 2194 /* Subtable: Memory Power Node(s) */ 2195 2196 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0, 2197 &Subtable, TRUE); 2198 if (ACPI_FAILURE (Status)) 2199 { 2200 return (Status); 2201 } 2202 2203 ParentTable = DtPeekSubtable (); 2204 DtInsertSubtable (ParentTable, Subtable); 2205 DtPushSubtable (Subtable); 2206 2207 MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer); 2208 PowerStateCount = MpstPowerNode->NumPowerStates; 2209 ComponentCount = MpstPowerNode->NumPhysicalComponents; 2210 2211 ParentTable = DtPeekSubtable (); 2212 2213 /* Sub-subtables - Memory Power State Structure(s) */ 2214 2215 while (*PFieldList && PowerStateCount) 2216 { 2217 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A, 2218 &Subtable, TRUE); 2219 if (ACPI_FAILURE (Status)) 2220 { 2221 return (Status); 2222 } 2223 2224 DtInsertSubtable (ParentTable, Subtable); 2225 PowerStateCount--; 2226 } 2227 2228 /* Sub-subtables - Physical Component ID Structure(s) */ 2229 2230 while (*PFieldList && ComponentCount) 2231 { 2232 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B, 2233 &Subtable, TRUE); 2234 if (ACPI_FAILURE (Status)) 2235 { 2236 return (Status); 2237 } 2238 2239 DtInsertSubtable (ParentTable, Subtable); 2240 ComponentCount--; 2241 } 2242 2243 SubtableCount--; 2244 DtPopSubtable (); 2245 } 2246 2247 /* Subtable: Count of Memory Power State Characteristic structures */ 2248 2249 DtPopSubtable (); 2250 2251 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable, TRUE); 2252 if (ACPI_FAILURE (Status)) 2253 { 2254 return (Status); 2255 } 2256 2257 ParentTable = DtPeekSubtable (); 2258 DtInsertSubtable (ParentTable, Subtable); 2259 DtPushSubtable (Subtable); 2260 2261 MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer); 2262 SubtableCount = MpstDataHeader->CharacteristicsCount; 2263 2264 ParentTable = DtPeekSubtable (); 2265 2266 /* Subtable: Memory Power State Characteristics structure(s) */ 2267 2268 while (*PFieldList && SubtableCount) 2269 { 2270 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2, 2271 &Subtable, TRUE); 2272 if (ACPI_FAILURE (Status)) 2273 { 2274 return (Status); 2275 } 2276 2277 DtInsertSubtable (ParentTable, Subtable); 2278 SubtableCount--; 2279 } 2280 2281 DtPopSubtable (); 2282 return (AE_OK); 2283 } 2284 2285 2286 /****************************************************************************** 2287 * 2288 * FUNCTION: DtCompileMsct 2289 * 2290 * PARAMETERS: List - Current field list pointer 2291 * 2292 * RETURN: Status 2293 * 2294 * DESCRIPTION: Compile MSCT. 2295 * 2296 *****************************************************************************/ 2297 2298 ACPI_STATUS 2299 DtCompileMsct ( 2300 void **List) 2301 { 2302 ACPI_STATUS Status; 2303 2304 2305 Status = DtCompileTwoSubtables (List, 2306 AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0); 2307 return (Status); 2308 } 2309 2310 2311 /****************************************************************************** 2312 * 2313 * FUNCTION: DtCompileMtmr 2314 * 2315 * PARAMETERS: List - Current field list pointer 2316 * 2317 * RETURN: Status 2318 * 2319 * DESCRIPTION: Compile MTMR. 2320 * 2321 *****************************************************************************/ 2322 2323 ACPI_STATUS 2324 DtCompileMtmr ( 2325 void **List) 2326 { 2327 ACPI_STATUS Status; 2328 2329 2330 Status = DtCompileTwoSubtables (List, 2331 AcpiDmTableInfoMtmr, AcpiDmTableInfoMtmr0); 2332 return (Status); 2333 } 2334 2335 2336 /****************************************************************************** 2337 * 2338 * FUNCTION: DtCompileNfit 2339 * 2340 * PARAMETERS: List - Current field list pointer 2341 * 2342 * RETURN: Status 2343 * 2344 * DESCRIPTION: Compile NFIT. 2345 * 2346 *****************************************************************************/ 2347 2348 ACPI_STATUS 2349 DtCompileNfit ( 2350 void **List) 2351 { 2352 ACPI_STATUS Status; 2353 DT_SUBTABLE *Subtable; 2354 DT_SUBTABLE *ParentTable; 2355 DT_FIELD **PFieldList = (DT_FIELD **) List; 2356 DT_FIELD *SubtableStart; 2357 ACPI_NFIT_HEADER *NfitHeader; 2358 ACPI_DMTABLE_INFO *InfoTable; 2359 UINT32 Count; 2360 ACPI_NFIT_INTERLEAVE *Interleave = NULL; 2361 ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL; 2362 2363 /* Main table */ 2364 2365 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit, 2366 &Subtable, TRUE); 2367 if (ACPI_FAILURE (Status)) 2368 { 2369 return (Status); 2370 } 2371 2372 ParentTable = DtPeekSubtable (); 2373 DtInsertSubtable (ParentTable, Subtable); 2374 DtPushSubtable (Subtable); 2375 2376 /* Subtables */ 2377 2378 while (*PFieldList) 2379 { 2380 SubtableStart = *PFieldList; 2381 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfitHdr, 2382 &Subtable, TRUE); 2383 if (ACPI_FAILURE (Status)) 2384 { 2385 return (Status); 2386 } 2387 2388 ParentTable = DtPeekSubtable (); 2389 DtInsertSubtable (ParentTable, Subtable); 2390 DtPushSubtable (Subtable); 2391 2392 NfitHeader = ACPI_CAST_PTR (ACPI_NFIT_HEADER, Subtable->Buffer); 2393 2394 switch (NfitHeader->Type) 2395 { 2396 case ACPI_NFIT_TYPE_SYSTEM_ADDRESS: 2397 2398 InfoTable = AcpiDmTableInfoNfit0; 2399 break; 2400 2401 case ACPI_NFIT_TYPE_MEMORY_MAP: 2402 2403 InfoTable = AcpiDmTableInfoNfit1; 2404 break; 2405 2406 case ACPI_NFIT_TYPE_INTERLEAVE: 2407 2408 Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable->Buffer); 2409 InfoTable = AcpiDmTableInfoNfit2; 2410 break; 2411 2412 case ACPI_NFIT_TYPE_SMBIOS: 2413 2414 InfoTable = AcpiDmTableInfoNfit3; 2415 break; 2416 2417 case ACPI_NFIT_TYPE_CONTROL_REGION: 2418 2419 InfoTable = AcpiDmTableInfoNfit4; 2420 break; 2421 2422 case ACPI_NFIT_TYPE_DATA_REGION: 2423 2424 InfoTable = AcpiDmTableInfoNfit5; 2425 break; 2426 2427 case ACPI_NFIT_TYPE_FLUSH_ADDRESS: 2428 2429 Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable->Buffer); 2430 InfoTable = AcpiDmTableInfoNfit6; 2431 break; 2432 2433 default: 2434 2435 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "NFIT"); 2436 return (AE_ERROR); 2437 } 2438 2439 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 2440 if (ACPI_FAILURE (Status)) 2441 { 2442 return (Status); 2443 } 2444 2445 ParentTable = DtPeekSubtable (); 2446 DtInsertSubtable (ParentTable, Subtable); 2447 DtPopSubtable (); 2448 2449 switch (NfitHeader->Type) 2450 { 2451 case ACPI_NFIT_TYPE_INTERLEAVE: 2452 2453 Count = 0; 2454 DtPushSubtable (Subtable); 2455 while (*PFieldList) 2456 { 2457 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit2a, 2458 &Subtable, FALSE); 2459 if (ACPI_FAILURE (Status)) 2460 { 2461 return (Status); 2462 } 2463 if (!Subtable) 2464 { 2465 DtPopSubtable (); 2466 break; 2467 } 2468 2469 ParentTable = DtPeekSubtable (); 2470 DtInsertSubtable (ParentTable, Subtable); 2471 Count++; 2472 } 2473 2474 Interleave->LineCount = Count; 2475 DtPopSubtable (); 2476 break; 2477 2478 case ACPI_NFIT_TYPE_SMBIOS: 2479 2480 if (*PFieldList) 2481 { 2482 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit3a, 2483 &Subtable, TRUE); 2484 if (ACPI_FAILURE (Status)) 2485 { 2486 return (Status); 2487 } 2488 if (Subtable) 2489 { 2490 DtInsertSubtable (ParentTable, Subtable); 2491 } 2492 } 2493 break; 2494 2495 case ACPI_NFIT_TYPE_FLUSH_ADDRESS: 2496 2497 Count = 0; 2498 DtPushSubtable (Subtable); 2499 while (*PFieldList) 2500 { 2501 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit6a, 2502 &Subtable, FALSE); 2503 if (ACPI_FAILURE (Status)) 2504 { 2505 return (Status); 2506 } 2507 if (!Subtable) 2508 { 2509 DtPopSubtable (); 2510 break; 2511 } 2512 2513 ParentTable = DtPeekSubtable (); 2514 DtInsertSubtable (ParentTable, Subtable); 2515 Count++; 2516 } 2517 2518 Hint->HintCount = (UINT16) Count; 2519 DtPopSubtable (); 2520 break; 2521 2522 default: 2523 break; 2524 } 2525 } 2526 2527 return (AE_OK); 2528 } 2529 2530 2531 /****************************************************************************** 2532 * 2533 * FUNCTION: DtCompilePcct 2534 * 2535 * PARAMETERS: List - Current field list pointer 2536 * 2537 * RETURN: Status 2538 * 2539 * DESCRIPTION: Compile PCCT. 2540 * 2541 *****************************************************************************/ 2542 2543 ACPI_STATUS 2544 DtCompilePcct ( 2545 void **List) 2546 { 2547 ACPI_STATUS Status; 2548 DT_SUBTABLE *Subtable; 2549 DT_SUBTABLE *ParentTable; 2550 DT_FIELD **PFieldList = (DT_FIELD **) List; 2551 DT_FIELD *SubtableStart; 2552 ACPI_SUBTABLE_HEADER *PcctHeader; 2553 ACPI_DMTABLE_INFO *InfoTable; 2554 2555 2556 /* Main table */ 2557 2558 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct, 2559 &Subtable, TRUE); 2560 if (ACPI_FAILURE (Status)) 2561 { 2562 return (Status); 2563 } 2564 2565 ParentTable = DtPeekSubtable (); 2566 DtInsertSubtable (ParentTable, Subtable); 2567 2568 /* Subtables */ 2569 2570 while (*PFieldList) 2571 { 2572 SubtableStart = *PFieldList; 2573 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr, 2574 &Subtable, TRUE); 2575 if (ACPI_FAILURE (Status)) 2576 { 2577 return (Status); 2578 } 2579 2580 ParentTable = DtPeekSubtable (); 2581 DtInsertSubtable (ParentTable, Subtable); 2582 DtPushSubtable (Subtable); 2583 2584 PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 2585 2586 switch (PcctHeader->Type) 2587 { 2588 case ACPI_PCCT_TYPE_GENERIC_SUBSPACE: 2589 2590 InfoTable = AcpiDmTableInfoPcct0; 2591 break; 2592 2593 case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE: 2594 2595 InfoTable = AcpiDmTableInfoPcct1; 2596 break; 2597 2598 default: 2599 2600 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT"); 2601 return (AE_ERROR); 2602 } 2603 2604 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 2605 if (ACPI_FAILURE (Status)) 2606 { 2607 return (Status); 2608 } 2609 2610 ParentTable = DtPeekSubtable (); 2611 DtInsertSubtable (ParentTable, Subtable); 2612 DtPopSubtable (); 2613 } 2614 2615 return (AE_OK); 2616 } 2617 2618 2619 /****************************************************************************** 2620 * 2621 * FUNCTION: DtCompilePmtt 2622 * 2623 * PARAMETERS: List - Current field list pointer 2624 * 2625 * RETURN: Status 2626 * 2627 * DESCRIPTION: Compile PMTT. 2628 * 2629 *****************************************************************************/ 2630 2631 ACPI_STATUS 2632 DtCompilePmtt ( 2633 void **List) 2634 { 2635 ACPI_STATUS Status; 2636 DT_SUBTABLE *Subtable; 2637 DT_SUBTABLE *ParentTable; 2638 DT_FIELD **PFieldList = (DT_FIELD **) List; 2639 DT_FIELD *SubtableStart; 2640 ACPI_PMTT_HEADER *PmttHeader; 2641 ACPI_PMTT_CONTROLLER *PmttController; 2642 UINT16 DomainCount; 2643 UINT8 PrevType = ACPI_PMTT_TYPE_SOCKET; 2644 2645 2646 /* Main table */ 2647 2648 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable, TRUE); 2649 if (ACPI_FAILURE (Status)) 2650 { 2651 return (Status); 2652 } 2653 2654 ParentTable = DtPeekSubtable (); 2655 DtInsertSubtable (ParentTable, Subtable); 2656 DtPushSubtable (Subtable); 2657 2658 while (*PFieldList) 2659 { 2660 SubtableStart = *PFieldList; 2661 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttHdr, 2662 &Subtable, TRUE); 2663 if (ACPI_FAILURE (Status)) 2664 { 2665 return (Status); 2666 } 2667 2668 PmttHeader = ACPI_CAST_PTR (ACPI_PMTT_HEADER, Subtable->Buffer); 2669 while (PrevType >= PmttHeader->Type) 2670 { 2671 DtPopSubtable (); 2672 2673 if (PrevType == ACPI_PMTT_TYPE_SOCKET) 2674 { 2675 break; 2676 } 2677 PrevType--; 2678 } 2679 PrevType = PmttHeader->Type; 2680 2681 ParentTable = DtPeekSubtable (); 2682 DtInsertSubtable (ParentTable, Subtable); 2683 DtPushSubtable (Subtable); 2684 2685 switch (PmttHeader->Type) 2686 { 2687 case ACPI_PMTT_TYPE_SOCKET: 2688 2689 /* Subtable: Socket Structure */ 2690 2691 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0, 2692 &Subtable, TRUE); 2693 if (ACPI_FAILURE (Status)) 2694 { 2695 return (Status); 2696 } 2697 2698 ParentTable = DtPeekSubtable (); 2699 DtInsertSubtable (ParentTable, Subtable); 2700 break; 2701 2702 case ACPI_PMTT_TYPE_CONTROLLER: 2703 2704 /* Subtable: Memory Controller Structure */ 2705 2706 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1, 2707 &Subtable, TRUE); 2708 if (ACPI_FAILURE (Status)) 2709 { 2710 return (Status); 2711 } 2712 2713 ParentTable = DtPeekSubtable (); 2714 DtInsertSubtable (ParentTable, Subtable); 2715 2716 PmttController = ACPI_CAST_PTR (ACPI_PMTT_CONTROLLER, 2717 (Subtable->Buffer - sizeof (ACPI_PMTT_HEADER))); 2718 DomainCount = PmttController->DomainCount; 2719 2720 while (DomainCount) 2721 { 2722 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1a, 2723 &Subtable, TRUE); 2724 if (ACPI_FAILURE (Status)) 2725 { 2726 return (Status); 2727 } 2728 2729 DtInsertSubtable (ParentTable, Subtable); 2730 DomainCount--; 2731 } 2732 break; 2733 2734 case ACPI_PMTT_TYPE_DIMM: 2735 2736 /* Subtable: Physical Component Structure */ 2737 2738 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2, 2739 &Subtable, TRUE); 2740 if (ACPI_FAILURE (Status)) 2741 { 2742 return (Status); 2743 } 2744 2745 ParentTable = DtPeekSubtable (); 2746 DtInsertSubtable (ParentTable, Subtable); 2747 break; 2748 2749 default: 2750 2751 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT"); 2752 return (AE_ERROR); 2753 } 2754 } 2755 2756 return (Status); 2757 } 2758 2759 2760 /****************************************************************************** 2761 * 2762 * FUNCTION: DtCompileRsdt 2763 * 2764 * PARAMETERS: List - Current field list pointer 2765 * 2766 * RETURN: Status 2767 * 2768 * DESCRIPTION: Compile RSDT. 2769 * 2770 *****************************************************************************/ 2771 2772 ACPI_STATUS 2773 DtCompileRsdt ( 2774 void **List) 2775 { 2776 DT_SUBTABLE *Subtable; 2777 DT_SUBTABLE *ParentTable; 2778 DT_FIELD *FieldList = *(DT_FIELD **) List; 2779 UINT32 Address; 2780 2781 2782 ParentTable = DtPeekSubtable (); 2783 2784 while (FieldList) 2785 { 2786 DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO); 2787 2788 DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable); 2789 DtInsertSubtable (ParentTable, Subtable); 2790 FieldList = FieldList->Next; 2791 } 2792 2793 return (AE_OK); 2794 } 2795 2796 2797 /****************************************************************************** 2798 * 2799 * FUNCTION: DtCompileS3pt 2800 * 2801 * PARAMETERS: PFieldList - Current field list pointer 2802 * 2803 * RETURN: Status 2804 * 2805 * DESCRIPTION: Compile S3PT (Pointed to by FPDT) 2806 * 2807 *****************************************************************************/ 2808 2809 ACPI_STATUS 2810 DtCompileS3pt ( 2811 DT_FIELD **PFieldList) 2812 { 2813 ACPI_STATUS Status; 2814 ACPI_S3PT_HEADER *S3ptHeader; 2815 DT_SUBTABLE *Subtable; 2816 DT_SUBTABLE *ParentTable; 2817 ACPI_DMTABLE_INFO *InfoTable; 2818 DT_FIELD *SubtableStart; 2819 2820 2821 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt, 2822 &Gbl_RootTable, TRUE); 2823 if (ACPI_FAILURE (Status)) 2824 { 2825 return (Status); 2826 } 2827 2828 DtPushSubtable (Gbl_RootTable); 2829 2830 while (*PFieldList) 2831 { 2832 SubtableStart = *PFieldList; 2833 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr, 2834 &Subtable, TRUE); 2835 if (ACPI_FAILURE (Status)) 2836 { 2837 return (Status); 2838 } 2839 2840 ParentTable = DtPeekSubtable (); 2841 DtInsertSubtable (ParentTable, Subtable); 2842 DtPushSubtable (Subtable); 2843 2844 S3ptHeader = ACPI_CAST_PTR (ACPI_S3PT_HEADER, Subtable->Buffer); 2845 2846 switch (S3ptHeader->Type) 2847 { 2848 case ACPI_S3PT_TYPE_RESUME: 2849 2850 InfoTable = AcpiDmTableInfoS3pt0; 2851 break; 2852 2853 case ACPI_S3PT_TYPE_SUSPEND: 2854 2855 InfoTable = AcpiDmTableInfoS3pt1; 2856 break; 2857 2858 default: 2859 2860 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT"); 2861 return (AE_ERROR); 2862 } 2863 2864 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 2865 if (ACPI_FAILURE (Status)) 2866 { 2867 return (Status); 2868 } 2869 2870 ParentTable = DtPeekSubtable (); 2871 DtInsertSubtable (ParentTable, Subtable); 2872 DtPopSubtable (); 2873 } 2874 2875 return (AE_OK); 2876 } 2877 2878 2879 /****************************************************************************** 2880 * 2881 * FUNCTION: DtCompileSlic 2882 * 2883 * PARAMETERS: List - Current field list pointer 2884 * 2885 * RETURN: Status 2886 * 2887 * DESCRIPTION: Compile SLIC. 2888 * 2889 *****************************************************************************/ 2890 2891 ACPI_STATUS 2892 DtCompileSlic ( 2893 void **List) 2894 { 2895 ACPI_STATUS Status; 2896 DT_SUBTABLE *Subtable; 2897 DT_SUBTABLE *ParentTable; 2898 DT_FIELD **PFieldList = (DT_FIELD **) List; 2899 2900 2901 while (*PFieldList) 2902 { 2903 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic, 2904 &Subtable, TRUE); 2905 if (ACPI_FAILURE (Status)) 2906 { 2907 return (Status); 2908 } 2909 2910 ParentTable = DtPeekSubtable (); 2911 DtInsertSubtable (ParentTable, Subtable); 2912 DtPushSubtable (Subtable); 2913 DtPopSubtable (); 2914 } 2915 2916 return (AE_OK); 2917 } 2918 2919 2920 /****************************************************************************** 2921 * 2922 * FUNCTION: DtCompileSlit 2923 * 2924 * PARAMETERS: List - Current field list pointer 2925 * 2926 * RETURN: Status 2927 * 2928 * DESCRIPTION: Compile SLIT. 2929 * 2930 *****************************************************************************/ 2931 2932 ACPI_STATUS 2933 DtCompileSlit ( 2934 void **List) 2935 { 2936 ACPI_STATUS Status; 2937 DT_SUBTABLE *Subtable; 2938 DT_SUBTABLE *ParentTable; 2939 DT_FIELD **PFieldList = (DT_FIELD **) List; 2940 DT_FIELD *FieldList; 2941 UINT32 Localities; 2942 UINT8 *LocalityBuffer; 2943 2944 2945 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit, 2946 &Subtable, TRUE); 2947 if (ACPI_FAILURE (Status)) 2948 { 2949 return (Status); 2950 } 2951 2952 ParentTable = DtPeekSubtable (); 2953 DtInsertSubtable (ParentTable, Subtable); 2954 2955 Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer); 2956 LocalityBuffer = UtLocalCalloc (Localities); 2957 2958 /* Compile each locality buffer */ 2959 2960 FieldList = *PFieldList; 2961 while (FieldList) 2962 { 2963 DtCompileBuffer (LocalityBuffer, 2964 FieldList->Value, FieldList, Localities); 2965 2966 DtCreateSubtable (LocalityBuffer, Localities, &Subtable); 2967 DtInsertSubtable (ParentTable, Subtable); 2968 FieldList = FieldList->Next; 2969 } 2970 2971 ACPI_FREE (LocalityBuffer); 2972 return (AE_OK); 2973 } 2974 2975 2976 /****************************************************************************** 2977 * 2978 * FUNCTION: DtCompileSrat 2979 * 2980 * PARAMETERS: List - Current field list pointer 2981 * 2982 * RETURN: Status 2983 * 2984 * DESCRIPTION: Compile SRAT. 2985 * 2986 *****************************************************************************/ 2987 2988 ACPI_STATUS 2989 DtCompileSrat ( 2990 void **List) 2991 { 2992 ACPI_STATUS Status; 2993 DT_SUBTABLE *Subtable; 2994 DT_SUBTABLE *ParentTable; 2995 DT_FIELD **PFieldList = (DT_FIELD **) List; 2996 DT_FIELD *SubtableStart; 2997 ACPI_SUBTABLE_HEADER *SratHeader; 2998 ACPI_DMTABLE_INFO *InfoTable; 2999 3000 3001 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat, 3002 &Subtable, TRUE); 3003 if (ACPI_FAILURE (Status)) 3004 { 3005 return (Status); 3006 } 3007 3008 ParentTable = DtPeekSubtable (); 3009 DtInsertSubtable (ParentTable, Subtable); 3010 3011 while (*PFieldList) 3012 { 3013 SubtableStart = *PFieldList; 3014 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr, 3015 &Subtable, TRUE); 3016 if (ACPI_FAILURE (Status)) 3017 { 3018 return (Status); 3019 } 3020 3021 ParentTable = DtPeekSubtable (); 3022 DtInsertSubtable (ParentTable, Subtable); 3023 DtPushSubtable (Subtable); 3024 3025 SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 3026 3027 switch (SratHeader->Type) 3028 { 3029 case ACPI_SRAT_TYPE_CPU_AFFINITY: 3030 3031 InfoTable = AcpiDmTableInfoSrat0; 3032 break; 3033 3034 case ACPI_SRAT_TYPE_MEMORY_AFFINITY: 3035 3036 InfoTable = AcpiDmTableInfoSrat1; 3037 break; 3038 3039 case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: 3040 3041 InfoTable = AcpiDmTableInfoSrat2; 3042 break; 3043 3044 case ACPI_SRAT_TYPE_GICC_AFFINITY: 3045 3046 InfoTable = AcpiDmTableInfoSrat3; 3047 break; 3048 3049 default: 3050 3051 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT"); 3052 return (AE_ERROR); 3053 } 3054 3055 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 3056 if (ACPI_FAILURE (Status)) 3057 { 3058 return (Status); 3059 } 3060 3061 ParentTable = DtPeekSubtable (); 3062 DtInsertSubtable (ParentTable, Subtable); 3063 DtPopSubtable (); 3064 } 3065 3066 return (AE_OK); 3067 } 3068 3069 3070 /****************************************************************************** 3071 * 3072 * FUNCTION: DtCompileStao 3073 * 3074 * PARAMETERS: PFieldList - Current field list pointer 3075 * 3076 * RETURN: Status 3077 * 3078 * DESCRIPTION: Compile STAO. 3079 * 3080 *****************************************************************************/ 3081 3082 ACPI_STATUS 3083 DtCompileStao ( 3084 void **List) 3085 { 3086 DT_FIELD **PFieldList = (DT_FIELD **) List; 3087 DT_SUBTABLE *Subtable; 3088 DT_SUBTABLE *ParentTable; 3089 ACPI_STATUS Status; 3090 3091 3092 /* Compile the main table */ 3093 3094 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao, 3095 &Subtable, TRUE); 3096 if (ACPI_FAILURE (Status)) 3097 { 3098 return (Status); 3099 } 3100 3101 ParentTable = DtPeekSubtable (); 3102 DtInsertSubtable (ParentTable, Subtable); 3103 3104 /* Compile each ASCII namestring as a subtable */ 3105 3106 while (*PFieldList) 3107 { 3108 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr, 3109 &Subtable, TRUE); 3110 if (ACPI_FAILURE (Status)) 3111 { 3112 return (Status); 3113 } 3114 3115 ParentTable = DtPeekSubtable (); 3116 DtInsertSubtable (ParentTable, Subtable); 3117 } 3118 3119 return (AE_OK); 3120 } 3121 3122 3123 /****************************************************************************** 3124 * 3125 * FUNCTION: DtCompileTcpa 3126 * 3127 * PARAMETERS: PFieldList - Current field list pointer 3128 * 3129 * RETURN: Status 3130 * 3131 * DESCRIPTION: Compile TCPA. 3132 * 3133 *****************************************************************************/ 3134 3135 ACPI_STATUS 3136 DtCompileTcpa ( 3137 void **List) 3138 { 3139 DT_FIELD **PFieldList = (DT_FIELD **) List; 3140 DT_SUBTABLE *Subtable; 3141 ACPI_TABLE_TCPA_HDR *TcpaHeader; 3142 DT_SUBTABLE *ParentTable; 3143 ACPI_STATUS Status; 3144 3145 3146 /* Compile the main table */ 3147 3148 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr, 3149 &Subtable, TRUE); 3150 if (ACPI_FAILURE (Status)) 3151 { 3152 return (Status); 3153 } 3154 3155 ParentTable = DtPeekSubtable (); 3156 DtInsertSubtable (ParentTable, Subtable); 3157 3158 /* 3159 * Examine the PlatformClass field to determine the table type. 3160 * Either a client or server table. Only one. 3161 */ 3162 TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer); 3163 3164 switch (TcpaHeader->PlatformClass) 3165 { 3166 case ACPI_TCPA_CLIENT_TABLE: 3167 3168 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient, 3169 &Subtable, TRUE); 3170 break; 3171 3172 case ACPI_TCPA_SERVER_TABLE: 3173 3174 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer, 3175 &Subtable, TRUE); 3176 break; 3177 3178 default: 3179 3180 AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n", 3181 TcpaHeader->PlatformClass); 3182 Status = AE_ERROR; 3183 break; 3184 } 3185 3186 3187 ParentTable = DtPeekSubtable (); 3188 DtInsertSubtable (ParentTable, Subtable); 3189 3190 return (Status); 3191 } 3192 3193 3194 /****************************************************************************** 3195 * 3196 * FUNCTION: DtGetGenericTableInfo 3197 * 3198 * PARAMETERS: Name - Generic type name 3199 * 3200 * RETURN: Info entry 3201 * 3202 * DESCRIPTION: Obtain table info for a generic name entry 3203 * 3204 *****************************************************************************/ 3205 3206 ACPI_DMTABLE_INFO * 3207 DtGetGenericTableInfo ( 3208 char *Name) 3209 { 3210 ACPI_DMTABLE_INFO *Info; 3211 UINT32 i; 3212 3213 3214 if (!Name) 3215 { 3216 return (NULL); 3217 } 3218 3219 /* Search info table for name match */ 3220 3221 for (i = 0; ; i++) 3222 { 3223 Info = AcpiDmTableInfoGeneric[i]; 3224 if (Info->Opcode == ACPI_DMT_EXIT) 3225 { 3226 Info = NULL; 3227 break; 3228 } 3229 3230 /* Use caseless compare for generic keywords */ 3231 3232 if (!AcpiUtStricmp (Name, Info->Name)) 3233 { 3234 break; 3235 } 3236 } 3237 3238 return (Info); 3239 } 3240 3241 3242 /****************************************************************************** 3243 * 3244 * FUNCTION: DtCompileUefi 3245 * 3246 * PARAMETERS: List - Current field list pointer 3247 * 3248 * RETURN: Status 3249 * 3250 * DESCRIPTION: Compile UEFI. 3251 * 3252 *****************************************************************************/ 3253 3254 ACPI_STATUS 3255 DtCompileUefi ( 3256 void **List) 3257 { 3258 ACPI_STATUS Status; 3259 DT_SUBTABLE *Subtable; 3260 DT_SUBTABLE *ParentTable; 3261 DT_FIELD **PFieldList = (DT_FIELD **) List; 3262 UINT16 *DataOffset; 3263 3264 3265 /* Compile the predefined portion of the UEFI table */ 3266 3267 Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi, 3268 &Subtable, TRUE); 3269 if (ACPI_FAILURE (Status)) 3270 { 3271 return (Status); 3272 } 3273 3274 DataOffset = (UINT16 *) (Subtable->Buffer + 16); 3275 *DataOffset = sizeof (ACPI_TABLE_UEFI); 3276 3277 ParentTable = DtPeekSubtable (); 3278 DtInsertSubtable (ParentTable, Subtable); 3279 3280 /* 3281 * Compile the "generic" portion of the UEFI table. This 3282 * part of the table is not predefined and any of the generic 3283 * operators may be used. 3284 */ 3285 3286 DtCompileGeneric ((void **) PFieldList, NULL, NULL); 3287 3288 return (AE_OK); 3289 } 3290 3291 3292 /****************************************************************************** 3293 * 3294 * FUNCTION: DtCompileVrtc 3295 * 3296 * PARAMETERS: List - Current field list pointer 3297 * 3298 * RETURN: Status 3299 * 3300 * DESCRIPTION: Compile VRTC. 3301 * 3302 *****************************************************************************/ 3303 3304 ACPI_STATUS 3305 DtCompileVrtc ( 3306 void **List) 3307 { 3308 ACPI_STATUS Status; 3309 3310 3311 Status = DtCompileTwoSubtables (List, 3312 AcpiDmTableInfoVrtc, AcpiDmTableInfoVrtc0); 3313 return (Status); 3314 } 3315 3316 3317 /****************************************************************************** 3318 * 3319 * FUNCTION: DtCompileWdat 3320 * 3321 * PARAMETERS: List - Current field list pointer 3322 * 3323 * RETURN: Status 3324 * 3325 * DESCRIPTION: Compile WDAT. 3326 * 3327 *****************************************************************************/ 3328 3329 ACPI_STATUS 3330 DtCompileWdat ( 3331 void **List) 3332 { 3333 ACPI_STATUS Status; 3334 3335 3336 Status = DtCompileTwoSubtables (List, 3337 AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0); 3338 return (Status); 3339 } 3340 3341 3342 /****************************************************************************** 3343 * 3344 * FUNCTION: DtCompileWpbt 3345 * 3346 * PARAMETERS: List - Current field list pointer 3347 * 3348 * RETURN: Status 3349 * 3350 * DESCRIPTION: Compile WPBT. 3351 * 3352 *****************************************************************************/ 3353 3354 ACPI_STATUS 3355 DtCompileWpbt ( 3356 void **List) 3357 { 3358 DT_FIELD **PFieldList = (DT_FIELD **) List; 3359 DT_SUBTABLE *Subtable; 3360 DT_SUBTABLE *ParentTable; 3361 ACPI_TABLE_WPBT *Table; 3362 ACPI_STATUS Status; 3363 UINT16 Length; 3364 3365 3366 /* Compile the main table */ 3367 3368 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt, 3369 &Subtable, TRUE); 3370 if (ACPI_FAILURE (Status)) 3371 { 3372 return (Status); 3373 } 3374 3375 ParentTable = DtPeekSubtable (); 3376 DtInsertSubtable (ParentTable, Subtable); 3377 3378 /* Compile the argument list subtable */ 3379 3380 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0, 3381 &Subtable, TRUE); 3382 if (ACPI_FAILURE (Status)) 3383 { 3384 return (Status); 3385 } 3386 3387 /* Extract the length of the Arguments buffer, insert into main table */ 3388 3389 Length = (UINT16) Subtable->TotalLength; 3390 Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer); 3391 Table->ArgumentsLength = Length; 3392 3393 ParentTable = DtPeekSubtable (); 3394 DtInsertSubtable (ParentTable, Subtable); 3395 return (AE_OK); 3396 } 3397 3398 3399 /****************************************************************************** 3400 * 3401 * FUNCTION: DtCompileXsdt 3402 * 3403 * PARAMETERS: List - Current field list pointer 3404 * 3405 * RETURN: Status 3406 * 3407 * DESCRIPTION: Compile XSDT. 3408 * 3409 *****************************************************************************/ 3410 3411 ACPI_STATUS 3412 DtCompileXsdt ( 3413 void **List) 3414 { 3415 DT_SUBTABLE *Subtable; 3416 DT_SUBTABLE *ParentTable; 3417 DT_FIELD *FieldList = *(DT_FIELD **) List; 3418 UINT64 Address; 3419 3420 3421 ParentTable = DtPeekSubtable (); 3422 3423 while (FieldList) 3424 { 3425 DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO); 3426 3427 DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable); 3428 DtInsertSubtable (ParentTable, Subtable); 3429 FieldList = FieldList->Next; 3430 } 3431 3432 return (AE_OK); 3433 } 3434 3435 3436 /****************************************************************************** 3437 * 3438 * FUNCTION: DtCompileGeneric 3439 * 3440 * PARAMETERS: List - Current field list pointer 3441 * Name - Field name to end generic compiling 3442 * Length - Compiled table length to return 3443 * 3444 * RETURN: Status 3445 * 3446 * DESCRIPTION: Compile generic unknown table. 3447 * 3448 *****************************************************************************/ 3449 3450 ACPI_STATUS 3451 DtCompileGeneric ( 3452 void **List, 3453 char *Name, 3454 UINT32 *Length) 3455 { 3456 ACPI_STATUS Status; 3457 DT_SUBTABLE *Subtable; 3458 DT_SUBTABLE *ParentTable; 3459 DT_FIELD **PFieldList = (DT_FIELD **) List; 3460 ACPI_DMTABLE_INFO *Info; 3461 3462 3463 ParentTable = DtPeekSubtable (); 3464 3465 /* 3466 * Compile the "generic" portion of the table. This 3467 * part of the table is not predefined and any of the generic 3468 * operators may be used. 3469 */ 3470 3471 /* Find any and all labels in the entire generic portion */ 3472 3473 DtDetectAllLabels (*PFieldList); 3474 3475 /* Now we can actually compile the parse tree */ 3476 3477 if (Length && *Length) 3478 { 3479 *Length = 0; 3480 } 3481 while (*PFieldList) 3482 { 3483 if (Name && !strcmp ((*PFieldList)->Name, Name)) 3484 { 3485 break; 3486 } 3487 Info = DtGetGenericTableInfo ((*PFieldList)->Name); 3488 if (!Info) 3489 { 3490 sprintf (MsgBuffer, "Generic data type \"%s\" not found", 3491 (*PFieldList)->Name); 3492 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 3493 (*PFieldList), MsgBuffer); 3494 3495 *PFieldList = (*PFieldList)->Next; 3496 continue; 3497 } 3498 3499 Status = DtCompileTable (PFieldList, Info, 3500 &Subtable, TRUE); 3501 if (ACPI_SUCCESS (Status)) 3502 { 3503 DtInsertSubtable (ParentTable, Subtable); 3504 if (Length) 3505 { 3506 *Length += Subtable->Length; 3507 } 3508 } 3509 else 3510 { 3511 *PFieldList = (*PFieldList)->Next; 3512 3513 if (Status == AE_NOT_FOUND) 3514 { 3515 sprintf (MsgBuffer, "Generic data type \"%s\" not found", 3516 (*PFieldList)->Name); 3517 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 3518 (*PFieldList), MsgBuffer); 3519 } 3520 } 3521 } 3522 3523 return (AE_OK); 3524 } 3525