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