1 /****************************************************************************** 2 * 3 * Module Name: dttable2.c - handling for specific ACPI tables 4 * 5 *****************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2022, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 ***************************************************************************** 115 * 116 * Alternatively, you may choose to be licensed under the terms of the 117 * following license: 118 * 119 * Redistribution and use in source and binary forms, with or without 120 * modification, are permitted provided that the following conditions 121 * are met: 122 * 1. Redistributions of source code must retain the above copyright 123 * notice, this list of conditions, and the following disclaimer, 124 * without modification. 125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126 * substantially similar to the "NO WARRANTY" disclaimer below 127 * ("Disclaimer") and any redistribution must be conditioned upon 128 * including a substantially similar Disclaimer requirement for further 129 * binary redistribution. 130 * 3. Neither the names of the above-listed copyright holders nor the names 131 * of any contributors may be used to endorse or promote products derived 132 * from this software without specific prior written permission. 133 * 134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145 * 146 * Alternatively, you may choose to be licensed under the terms of the 147 * GNU General Public License ("GPL") version 2 as published by the Free 148 * Software Foundation. 149 * 150 *****************************************************************************/ 151 152 /* Compile all complex data tables, signatures starting with L-Z */ 153 154 #include <contrib/dev/acpica/compiler/aslcompiler.h> 155 156 #define _COMPONENT DT_COMPILER 157 ACPI_MODULE_NAME ("dttable2") 158 159 160 /****************************************************************************** 161 * 162 * FUNCTION: DtCompileLpit 163 * 164 * PARAMETERS: List - Current field list pointer 165 * 166 * RETURN: Status 167 * 168 * DESCRIPTION: Compile LPIT. 169 * 170 *****************************************************************************/ 171 172 ACPI_STATUS 173 DtCompileLpit ( 174 void **List) 175 { 176 ACPI_STATUS Status; 177 DT_SUBTABLE *Subtable; 178 DT_SUBTABLE *ParentTable; 179 DT_FIELD **PFieldList = (DT_FIELD **) List; 180 DT_FIELD *SubtableStart; 181 ACPI_DMTABLE_INFO *InfoTable; 182 ACPI_LPIT_HEADER *LpitHeader; 183 184 185 /* Note: Main table consists only of the standard ACPI table header */ 186 187 while (*PFieldList) 188 { 189 SubtableStart = *PFieldList; 190 191 /* LPIT Subtable header */ 192 193 Status = DtCompileTable (PFieldList, AcpiDmTableInfoLpitHdr, 194 &Subtable); 195 if (ACPI_FAILURE (Status)) 196 { 197 return (Status); 198 } 199 200 ParentTable = DtPeekSubtable (); 201 DtInsertSubtable (ParentTable, Subtable); 202 DtPushSubtable (Subtable); 203 204 LpitHeader = ACPI_CAST_PTR (ACPI_LPIT_HEADER, Subtable->Buffer); 205 206 switch (LpitHeader->Type) 207 { 208 case ACPI_LPIT_TYPE_NATIVE_CSTATE: 209 210 InfoTable = AcpiDmTableInfoLpit0; 211 break; 212 213 default: 214 215 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "LPIT"); 216 return (AE_ERROR); 217 } 218 219 /* LPIT Subtable */ 220 221 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 222 if (ACPI_FAILURE (Status)) 223 { 224 return (Status); 225 } 226 227 ParentTable = DtPeekSubtable (); 228 DtInsertSubtable (ParentTable, Subtable); 229 DtPopSubtable (); 230 } 231 232 return (AE_OK); 233 } 234 235 236 /****************************************************************************** 237 * 238 * FUNCTION: DtCompileMadt 239 * 240 * PARAMETERS: List - Current field list pointer 241 * 242 * RETURN: Status 243 * 244 * DESCRIPTION: Compile MADT. 245 * 246 *****************************************************************************/ 247 248 ACPI_STATUS 249 DtCompileMadt ( 250 void **List) 251 { 252 ACPI_STATUS Status; 253 DT_SUBTABLE *Subtable; 254 DT_SUBTABLE *ParentTable; 255 DT_FIELD **PFieldList = (DT_FIELD **) List; 256 DT_FIELD *SubtableStart; 257 ACPI_SUBTABLE_HEADER *MadtHeader; 258 ACPI_DMTABLE_INFO *InfoTable; 259 260 261 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt, 262 &Subtable); 263 if (ACPI_FAILURE (Status)) 264 { 265 return (Status); 266 } 267 268 ParentTable = DtPeekSubtable (); 269 DtInsertSubtable (ParentTable, Subtable); 270 271 while (*PFieldList) 272 { 273 SubtableStart = *PFieldList; 274 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr, 275 &Subtable); 276 if (ACPI_FAILURE (Status)) 277 { 278 return (Status); 279 } 280 281 ParentTable = DtPeekSubtable (); 282 DtInsertSubtable (ParentTable, Subtable); 283 DtPushSubtable (Subtable); 284 285 MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 286 287 switch (MadtHeader->Type) 288 { 289 case ACPI_MADT_TYPE_LOCAL_APIC: 290 291 InfoTable = AcpiDmTableInfoMadt0; 292 break; 293 294 case ACPI_MADT_TYPE_IO_APIC: 295 296 InfoTable = AcpiDmTableInfoMadt1; 297 break; 298 299 case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: 300 301 InfoTable = AcpiDmTableInfoMadt2; 302 break; 303 304 case ACPI_MADT_TYPE_NMI_SOURCE: 305 306 InfoTable = AcpiDmTableInfoMadt3; 307 break; 308 309 case ACPI_MADT_TYPE_LOCAL_APIC_NMI: 310 311 InfoTable = AcpiDmTableInfoMadt4; 312 break; 313 314 case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: 315 316 InfoTable = AcpiDmTableInfoMadt5; 317 break; 318 319 case ACPI_MADT_TYPE_IO_SAPIC: 320 321 InfoTable = AcpiDmTableInfoMadt6; 322 break; 323 324 case ACPI_MADT_TYPE_LOCAL_SAPIC: 325 326 InfoTable = AcpiDmTableInfoMadt7; 327 break; 328 329 case ACPI_MADT_TYPE_INTERRUPT_SOURCE: 330 331 InfoTable = AcpiDmTableInfoMadt8; 332 break; 333 334 case ACPI_MADT_TYPE_LOCAL_X2APIC: 335 336 InfoTable = AcpiDmTableInfoMadt9; 337 break; 338 339 case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI: 340 341 InfoTable = AcpiDmTableInfoMadt10; 342 break; 343 344 case ACPI_MADT_TYPE_GENERIC_INTERRUPT: 345 346 InfoTable = AcpiDmTableInfoMadt11; 347 break; 348 349 case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR: 350 351 InfoTable = AcpiDmTableInfoMadt12; 352 break; 353 354 case ACPI_MADT_TYPE_GENERIC_MSI_FRAME: 355 356 InfoTable = AcpiDmTableInfoMadt13; 357 break; 358 359 case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR: 360 361 InfoTable = AcpiDmTableInfoMadt14; 362 break; 363 364 case ACPI_MADT_TYPE_GENERIC_TRANSLATOR: 365 366 InfoTable = AcpiDmTableInfoMadt15; 367 break; 368 369 case ACPI_MADT_TYPE_MULTIPROC_WAKEUP: 370 371 InfoTable = AcpiDmTableInfoMadt16; 372 break; 373 374 default: 375 376 if (MadtHeader->Type >= ACPI_MADT_TYPE_OEM_RESERVED) 377 { 378 InfoTable = AcpiDmTableInfoMadt17; 379 } 380 else 381 { 382 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT"); 383 return (AE_ERROR); 384 } 385 386 break; 387 } 388 389 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 390 if (ACPI_FAILURE (Status)) 391 { 392 return (Status); 393 } 394 395 ParentTable = DtPeekSubtable (); 396 DtInsertSubtable (ParentTable, Subtable); 397 DtPopSubtable (); 398 } 399 400 return (AE_OK); 401 } 402 403 404 /****************************************************************************** 405 * 406 * FUNCTION: DtCompileMcfg 407 * 408 * PARAMETERS: List - Current field list pointer 409 * 410 * RETURN: Status 411 * 412 * DESCRIPTION: Compile MCFG. 413 * 414 *****************************************************************************/ 415 416 ACPI_STATUS 417 DtCompileMcfg ( 418 void **List) 419 { 420 ACPI_STATUS Status; 421 422 423 Status = DtCompileTwoSubtables (List, 424 AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0); 425 return (Status); 426 } 427 428 429 /****************************************************************************** 430 * 431 * FUNCTION: DtCompileMpst 432 * 433 * PARAMETERS: List - Current field list pointer 434 * 435 * RETURN: Status 436 * 437 * DESCRIPTION: Compile MPST. 438 * 439 *****************************************************************************/ 440 441 ACPI_STATUS 442 DtCompileMpst ( 443 void **List) 444 { 445 ACPI_STATUS Status; 446 DT_SUBTABLE *Subtable; 447 DT_SUBTABLE *ParentTable; 448 DT_FIELD **PFieldList = (DT_FIELD **) List; 449 ACPI_MPST_CHANNEL *MpstChannelInfo; 450 ACPI_MPST_POWER_NODE *MpstPowerNode; 451 ACPI_MPST_DATA_HDR *MpstDataHeader; 452 UINT16 SubtableCount; 453 UINT32 PowerStateCount; 454 UINT32 ComponentCount; 455 456 457 /* Main table */ 458 459 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable); 460 if (ACPI_FAILURE (Status)) 461 { 462 return (Status); 463 } 464 465 ParentTable = DtPeekSubtable (); 466 DtInsertSubtable (ParentTable, Subtable); 467 DtPushSubtable (Subtable); 468 469 MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer); 470 SubtableCount = MpstChannelInfo->PowerNodeCount; 471 472 while (*PFieldList && SubtableCount) 473 { 474 /* Subtable: Memory Power Node(s) */ 475 476 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0, 477 &Subtable); 478 if (ACPI_FAILURE (Status)) 479 { 480 return (Status); 481 } 482 483 ParentTable = DtPeekSubtable (); 484 DtInsertSubtable (ParentTable, Subtable); 485 DtPushSubtable (Subtable); 486 487 MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer); 488 PowerStateCount = MpstPowerNode->NumPowerStates; 489 ComponentCount = MpstPowerNode->NumPhysicalComponents; 490 491 ParentTable = DtPeekSubtable (); 492 493 /* Sub-subtables - Memory Power State Structure(s) */ 494 495 while (*PFieldList && PowerStateCount) 496 { 497 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A, 498 &Subtable); 499 if (ACPI_FAILURE (Status)) 500 { 501 return (Status); 502 } 503 504 DtInsertSubtable (ParentTable, Subtable); 505 PowerStateCount--; 506 } 507 508 /* Sub-subtables - Physical Component ID Structure(s) */ 509 510 while (*PFieldList && ComponentCount) 511 { 512 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B, 513 &Subtable); 514 if (ACPI_FAILURE (Status)) 515 { 516 return (Status); 517 } 518 519 DtInsertSubtable (ParentTable, Subtable); 520 ComponentCount--; 521 } 522 523 SubtableCount--; 524 DtPopSubtable (); 525 } 526 527 /* Subtable: Count of Memory Power State Characteristic structures */ 528 529 DtPopSubtable (); 530 531 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable); 532 if (ACPI_FAILURE (Status)) 533 { 534 return (Status); 535 } 536 537 ParentTable = DtPeekSubtable (); 538 DtInsertSubtable (ParentTable, Subtable); 539 DtPushSubtable (Subtable); 540 541 MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer); 542 SubtableCount = MpstDataHeader->CharacteristicsCount; 543 544 ParentTable = DtPeekSubtable (); 545 546 /* Subtable: Memory Power State Characteristics structure(s) */ 547 548 while (*PFieldList && SubtableCount) 549 { 550 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2, 551 &Subtable); 552 if (ACPI_FAILURE (Status)) 553 { 554 return (Status); 555 } 556 557 DtInsertSubtable (ParentTable, Subtable); 558 SubtableCount--; 559 } 560 561 DtPopSubtable (); 562 return (AE_OK); 563 } 564 565 566 /****************************************************************************** 567 * 568 * FUNCTION: DtCompileMsct 569 * 570 * PARAMETERS: List - Current field list pointer 571 * 572 * RETURN: Status 573 * 574 * DESCRIPTION: Compile MSCT. 575 * 576 *****************************************************************************/ 577 578 ACPI_STATUS 579 DtCompileMsct ( 580 void **List) 581 { 582 ACPI_STATUS Status; 583 584 585 Status = DtCompileTwoSubtables (List, 586 AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0); 587 return (Status); 588 } 589 590 591 /****************************************************************************** 592 * 593 * FUNCTION: DtCompileNfit 594 * 595 * PARAMETERS: List - Current field list pointer 596 * 597 * RETURN: Status 598 * 599 * DESCRIPTION: Compile NFIT. 600 * 601 *****************************************************************************/ 602 603 ACPI_STATUS 604 DtCompileNfit ( 605 void **List) 606 { 607 ACPI_STATUS Status; 608 DT_SUBTABLE *Subtable; 609 DT_SUBTABLE *ParentTable; 610 DT_FIELD **PFieldList = (DT_FIELD **) List; 611 DT_FIELD *SubtableStart; 612 ACPI_NFIT_HEADER *NfitHeader; 613 ACPI_DMTABLE_INFO *InfoTable; 614 UINT32 Count; 615 ACPI_NFIT_INTERLEAVE *Interleave = NULL; 616 ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL; 617 618 619 /* Main table */ 620 621 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit, 622 &Subtable); 623 if (ACPI_FAILURE (Status)) 624 { 625 return (Status); 626 } 627 628 ParentTable = DtPeekSubtable (); 629 DtInsertSubtable (ParentTable, Subtable); 630 DtPushSubtable (Subtable); 631 632 /* Subtables */ 633 634 while (*PFieldList) 635 { 636 SubtableStart = *PFieldList; 637 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfitHdr, 638 &Subtable); 639 if (ACPI_FAILURE (Status)) 640 { 641 return (Status); 642 } 643 644 ParentTable = DtPeekSubtable (); 645 DtInsertSubtable (ParentTable, Subtable); 646 DtPushSubtable (Subtable); 647 648 NfitHeader = ACPI_CAST_PTR (ACPI_NFIT_HEADER, Subtable->Buffer); 649 650 switch (NfitHeader->Type) 651 { 652 case ACPI_NFIT_TYPE_SYSTEM_ADDRESS: 653 654 InfoTable = AcpiDmTableInfoNfit0; 655 break; 656 657 case ACPI_NFIT_TYPE_MEMORY_MAP: 658 659 InfoTable = AcpiDmTableInfoNfit1; 660 break; 661 662 case ACPI_NFIT_TYPE_INTERLEAVE: 663 664 Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable->Buffer); 665 InfoTable = AcpiDmTableInfoNfit2; 666 break; 667 668 case ACPI_NFIT_TYPE_SMBIOS: 669 670 InfoTable = AcpiDmTableInfoNfit3; 671 break; 672 673 case ACPI_NFIT_TYPE_CONTROL_REGION: 674 675 InfoTable = AcpiDmTableInfoNfit4; 676 break; 677 678 case ACPI_NFIT_TYPE_DATA_REGION: 679 680 InfoTable = AcpiDmTableInfoNfit5; 681 break; 682 683 case ACPI_NFIT_TYPE_FLUSH_ADDRESS: 684 685 Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable->Buffer); 686 InfoTable = AcpiDmTableInfoNfit6; 687 break; 688 689 case ACPI_NFIT_TYPE_CAPABILITIES: 690 691 InfoTable = AcpiDmTableInfoNfit7; 692 break; 693 694 default: 695 696 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "NFIT"); 697 return (AE_ERROR); 698 } 699 700 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 701 if (ACPI_FAILURE (Status)) 702 { 703 return (Status); 704 } 705 706 ParentTable = DtPeekSubtable (); 707 DtInsertSubtable (ParentTable, Subtable); 708 DtPopSubtable (); 709 710 switch (NfitHeader->Type) 711 { 712 case ACPI_NFIT_TYPE_INTERLEAVE: 713 714 Count = 0; 715 DtPushSubtable (Subtable); 716 while (*PFieldList) 717 { 718 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit2a, 719 &Subtable); 720 if (ACPI_FAILURE (Status)) 721 { 722 return (Status); 723 } 724 725 if (!Subtable) 726 { 727 DtPopSubtable (); 728 break; 729 } 730 731 ParentTable = DtPeekSubtable (); 732 DtInsertSubtable (ParentTable, Subtable); 733 Count++; 734 } 735 736 Interleave->LineCount = Count; 737 break; 738 739 case ACPI_NFIT_TYPE_SMBIOS: 740 741 if (*PFieldList) 742 { 743 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit3a, 744 &Subtable); 745 if (ACPI_FAILURE (Status)) 746 { 747 return (Status); 748 } 749 750 if (Subtable) 751 { 752 DtInsertSubtable (ParentTable, Subtable); 753 } 754 } 755 break; 756 757 case ACPI_NFIT_TYPE_FLUSH_ADDRESS: 758 759 Count = 0; 760 DtPushSubtable (Subtable); 761 while (*PFieldList) 762 { 763 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit6a, 764 &Subtable); 765 if (ACPI_FAILURE (Status)) 766 { 767 return (Status); 768 } 769 770 if (!Subtable) 771 { 772 DtPopSubtable (); 773 break; 774 } 775 776 ParentTable = DtPeekSubtable (); 777 DtInsertSubtable (ParentTable, Subtable); 778 Count++; 779 } 780 781 Hint->HintCount = (UINT16) Count; 782 break; 783 784 default: 785 break; 786 } 787 } 788 789 return (AE_OK); 790 } 791 792 793 /****************************************************************************** 794 * 795 * FUNCTION: DtCompileNhlt 796 * 797 * PARAMETERS: List - Current field list pointer 798 * 799 * RETURN: Status 800 * 801 * DESCRIPTION: Compile NHLT. 802 * 803 *****************************************************************************/ 804 805 ACPI_STATUS 806 DtCompileNhlt ( 807 void **List) 808 { 809 ACPI_STATUS Status; 810 UINT32 EndpointCount; 811 UINT32 MicrophoneCount; 812 UINT32 FormatsCount; 813 DT_SUBTABLE *Subtable; 814 DT_SUBTABLE *ParentTable; 815 DT_FIELD **PFieldList = (DT_FIELD **) List; 816 UINT32 CapabilitiesSize; 817 UINT8 ArrayType; 818 UINT8 ConfigType; 819 UINT8 DeviceInfoCount; 820 UINT32 i; 821 UINT32 j; 822 ACPI_TABLE_NHLT_ENDPOINT_COUNT *MainTable; 823 ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A *DevSpecific; 824 ACPI_NHLT_VENDOR_MIC_COUNT *MicCount; 825 ACPI_NHLT_FORMATS_CONFIG *FormatsConfig; 826 ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_D *ConfigSpecific; 827 ACPI_NHLT_DEVICE_INFO_COUNT *DeviceInfo; 828 ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_B *Terminator; 829 830 831 /* Main table */ 832 833 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt, 834 &Subtable); 835 if (ACPI_FAILURE (Status)) 836 { 837 return (Status); 838 } 839 840 /* Get the Endpoint Descriptor count */ 841 842 ParentTable = DtPeekSubtable (); 843 DtInsertSubtable (ParentTable, Subtable); 844 DtPushSubtable (Subtable); 845 846 MainTable = ACPI_CAST_PTR (ACPI_TABLE_NHLT_ENDPOINT_COUNT, Subtable->Buffer); 847 EndpointCount = MainTable->EndpointCount; 848 849 /* Subtables */ 850 851 while (*PFieldList) 852 { 853 /* Variable number of Endpoint descriptors */ 854 855 for (i = 0; i < EndpointCount; i++) 856 { 857 /* Do the Endpoint Descriptor */ 858 859 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt0, 860 &Subtable); 861 if (ACPI_FAILURE (Status)) 862 { 863 return (Status); 864 } 865 866 ParentTable = DtPeekSubtable (); 867 DtInsertSubtable (ParentTable, Subtable); 868 DtPushSubtable (Subtable); 869 870 /* Do the Device Specific table */ 871 872 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5b, 873 &Subtable); 874 if (ACPI_FAILURE (Status)) 875 { 876 return (Status); 877 } 878 879 ParentTable = DtPeekSubtable (); 880 DtInsertSubtable (ParentTable, Subtable); 881 DtPushSubtable (Subtable); 882 883 DevSpecific = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A, Subtable->Buffer); 884 CapabilitiesSize = DevSpecific->CapabilitiesSize; 885 886 ArrayType = 0; 887 ConfigType = 0; 888 889 switch (CapabilitiesSize) 890 { 891 case 0: 892 break; 893 894 case 1: 895 896 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5c, 897 &Subtable); 898 if (ACPI_FAILURE (Status)) 899 { 900 return (Status); 901 } 902 903 ParentTable = DtPeekSubtable (); 904 DtInsertSubtable (ParentTable, Subtable); 905 break; 906 907 case 2: 908 909 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5, 910 &Subtable); 911 if (ACPI_FAILURE (Status)) 912 { 913 return (Status); 914 } 915 916 ParentTable = DtPeekSubtable (); 917 DtInsertSubtable (ParentTable, Subtable); 918 break; 919 920 case 3: 921 922 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5a, 923 &Subtable); 924 if (ACPI_FAILURE (Status)) 925 { 926 return (Status); 927 } 928 929 ParentTable = DtPeekSubtable (); 930 DtInsertSubtable (ParentTable, Subtable); 931 932 ConfigSpecific = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_D, Subtable->Buffer); 933 ArrayType = ConfigSpecific->ArrayType; 934 ConfigType = ConfigSpecific->ConfigType; 935 break; 936 937 case 7: 938 939 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5, 940 &Subtable); 941 if (ACPI_FAILURE (Status)) 942 { 943 return (Status); 944 } 945 946 ParentTable = DtPeekSubtable (); 947 DtInsertSubtable (ParentTable, Subtable); 948 949 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt6b, 950 &Subtable); 951 if (ACPI_FAILURE (Status)) 952 { 953 return (Status); 954 } 955 956 ParentTable = DtPeekSubtable (); 957 DtInsertSubtable (ParentTable, Subtable); 958 959 ConfigSpecific = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_D, Subtable->Buffer); 960 ArrayType = ConfigSpecific->ArrayType; 961 ConfigType = ConfigSpecific->ConfigType; 962 break; 963 964 default: 965 966 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5a, 967 &Subtable); 968 if (ACPI_FAILURE (Status)) 969 { 970 return (Status); 971 } 972 973 ParentTable = DtPeekSubtable (); 974 DtInsertSubtable (ParentTable, Subtable); 975 976 ConfigSpecific = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_D, Subtable->Buffer); 977 ArrayType = ConfigSpecific->ArrayType; 978 ConfigType = ConfigSpecific->ConfigType; 979 break; 980 981 } /* switch (CapabilitiesSize) */ 982 983 if (CapabilitiesSize >= 3) 984 { 985 /* Check for a vendor-defined mic array */ 986 987 if (ConfigType == ACPI_NHLT_CONFIG_TYPE_MIC_ARRAY) 988 { 989 if ((ArrayType & ACPI_NHLT_ARRAY_TYPE_MASK) == ACPI_NHLT_VENDOR_DEFINED) 990 { 991 /* Get the microphone count */ 992 993 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt6a, 994 &Subtable); 995 if (ACPI_FAILURE (Status)) 996 { 997 return (Status); 998 } 999 1000 MicCount = ACPI_CAST_PTR (ACPI_NHLT_VENDOR_MIC_COUNT, Subtable->Buffer); 1001 MicrophoneCount = MicCount->MicrophoneCount; 1002 1003 ParentTable = DtPeekSubtable (); 1004 DtInsertSubtable (ParentTable, Subtable); 1005 1006 /* Variable number of microphones */ 1007 1008 for (j = 0; j < MicrophoneCount; j++) 1009 { 1010 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt6, 1011 &Subtable); 1012 if (ACPI_FAILURE (Status)) 1013 { 1014 return (Status); 1015 } 1016 1017 ParentTable = DtPeekSubtable (); 1018 DtInsertSubtable (ParentTable, Subtable); 1019 } 1020 1021 /* Do the MIC_SNR_SENSITIVITY_EXTENSION, if present */ 1022 1023 if (ArrayType & ACPI_NHLT_ARRAY_TYPE_EXT_MASK) 1024 { 1025 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt9, 1026 &Subtable); 1027 if (ACPI_FAILURE (Status)) 1028 { 1029 return (Status); 1030 } 1031 1032 ParentTable = DtPeekSubtable (); 1033 DtInsertSubtable (ParentTable, Subtable); 1034 } 1035 } 1036 } 1037 } 1038 1039 /* Get the formats count */ 1040 1041 DtPopSubtable (); 1042 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt4, 1043 &Subtable); 1044 if (ACPI_FAILURE (Status)) 1045 { 1046 return (Status); 1047 } 1048 1049 ParentTable = DtPeekSubtable (); 1050 DtInsertSubtable (ParentTable, Subtable); 1051 1052 FormatsConfig = ACPI_CAST_PTR (ACPI_NHLT_FORMATS_CONFIG, Subtable->Buffer); 1053 FormatsCount = FormatsConfig->FormatsCount; 1054 1055 /* Variable number of wave_format_extensible structs */ 1056 1057 for (j = 0; j < FormatsCount; j++) 1058 { 1059 /* Do the main wave_format_extensible structure */ 1060 1061 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt3, 1062 &Subtable); 1063 if (ACPI_FAILURE (Status)) 1064 { 1065 return (Status); 1066 } 1067 1068 ParentTable = DtPeekSubtable (); 1069 DtInsertSubtable (ParentTable, Subtable); 1070 DtPushSubtable (Subtable); 1071 1072 /* Do the capabilities list */ 1073 1074 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt3a, 1075 &Subtable); 1076 if (ACPI_FAILURE (Status)) 1077 { 1078 return (Status); 1079 } 1080 1081 DtPopSubtable (); 1082 ParentTable = DtPeekSubtable (); 1083 DtInsertSubtable (ParentTable, Subtable); 1084 1085 } /* for (j = 0; j < FormatsCount; j++) */ 1086 1087 /* 1088 * If we are not done with the current Endpoint yet, then there must be 1089 * some non documeneted structure(s) yet to be processed. First, get 1090 * the count of such structure(s). 1091 */ 1092 if (*PFieldList && !(strcmp ((const char *) (*PFieldList)->Name, "Device Info struct count"))) 1093 { 1094 /* Get the count of non documented structures */ 1095 1096 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt7, 1097 &Subtable); 1098 if (ACPI_FAILURE (Status)) 1099 { 1100 return (Status); 1101 } 1102 1103 ParentTable = DtPeekSubtable (); 1104 DtInsertSubtable (ParentTable, Subtable); 1105 1106 DeviceInfo = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_INFO_COUNT, Subtable->Buffer); 1107 DeviceInfoCount = DeviceInfo->StructureCount; 1108 1109 for (j = 0; j < DeviceInfoCount; j++) 1110 { 1111 /* 1112 * Compile the following Device Info fields: 1113 * 1) Device ID 1114 * 2) Device Instance ID 1115 * 3) Device Port ID 1116 */ 1117 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt7a, 1118 &Subtable); 1119 if (ACPI_FAILURE (Status)) 1120 { 1121 return (Status); 1122 } 1123 1124 ParentTable = DtPeekSubtable (); 1125 DtInsertSubtable (ParentTable, Subtable); 1126 } /* for (j = 0; j < LinuxSpecificCount; j++) */ 1127 1128 /* Undocumented data at the end of endpoint */ 1129 if (*PFieldList && !(strcmp ((const char *) (*PFieldList)->Name, "Bytes"))) 1130 { 1131 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt7b, 1132 &Subtable); 1133 if (ACPI_FAILURE (Status)) 1134 { 1135 return (Status); 1136 } 1137 1138 ParentTable = DtPeekSubtable (); 1139 DtInsertSubtable (ParentTable, Subtable); 1140 } 1141 } 1142 1143 DtPopSubtable (); 1144 1145 } /* for (i = 0; i < EndpointCount; i++) */ 1146 1147 /* 1148 * All Endpoint Descriptors are completed. 1149 * Do the table terminator specific config (not in NHLT spec, optional) 1150 */ 1151 if (*PFieldList && !(strcmp ((const char *) (*PFieldList)->Name, "Capabilities Size"))) 1152 { 1153 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5b, 1154 &Subtable); 1155 if (ACPI_FAILURE (Status)) 1156 { 1157 return (Status); 1158 } 1159 1160 ParentTable = DtPeekSubtable (); 1161 DtInsertSubtable (ParentTable, Subtable); 1162 1163 Terminator = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_B, Subtable->Buffer); 1164 1165 if (Terminator->CapabilitiesSize) 1166 { 1167 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt3a, 1168 &Subtable); 1169 if (ACPI_FAILURE (Status)) 1170 { 1171 return (Status); 1172 } 1173 1174 ParentTable = DtPeekSubtable (); 1175 DtInsertSubtable (ParentTable, Subtable); 1176 } 1177 } 1178 1179 return (AE_OK); 1180 } 1181 1182 return (AE_OK); 1183 } 1184 1185 1186 /****************************************************************************** 1187 * 1188 * FUNCTION: DtCompilePcct 1189 * 1190 * PARAMETERS: List - Current field list pointer 1191 * 1192 * RETURN: Status 1193 * 1194 * DESCRIPTION: Compile PCCT. 1195 * 1196 *****************************************************************************/ 1197 1198 ACPI_STATUS 1199 DtCompilePcct ( 1200 void **List) 1201 { 1202 ACPI_STATUS Status; 1203 DT_SUBTABLE *Subtable; 1204 DT_SUBTABLE *ParentTable; 1205 DT_FIELD **PFieldList = (DT_FIELD **) List; 1206 DT_FIELD *SubtableStart; 1207 ACPI_SUBTABLE_HEADER *PcctHeader; 1208 ACPI_DMTABLE_INFO *InfoTable; 1209 1210 1211 /* Main table */ 1212 1213 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct, 1214 &Subtable); 1215 if (ACPI_FAILURE (Status)) 1216 { 1217 return (Status); 1218 } 1219 1220 ParentTable = DtPeekSubtable (); 1221 DtInsertSubtable (ParentTable, Subtable); 1222 1223 /* Subtables */ 1224 1225 while (*PFieldList) 1226 { 1227 SubtableStart = *PFieldList; 1228 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr, 1229 &Subtable); 1230 if (ACPI_FAILURE (Status)) 1231 { 1232 return (Status); 1233 } 1234 1235 ParentTable = DtPeekSubtable (); 1236 DtInsertSubtable (ParentTable, Subtable); 1237 DtPushSubtable (Subtable); 1238 1239 PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1240 1241 switch (PcctHeader->Type) 1242 { 1243 case ACPI_PCCT_TYPE_GENERIC_SUBSPACE: 1244 1245 InfoTable = AcpiDmTableInfoPcct0; 1246 break; 1247 1248 case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE: 1249 1250 InfoTable = AcpiDmTableInfoPcct1; 1251 break; 1252 1253 case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2: 1254 1255 InfoTable = AcpiDmTableInfoPcct2; 1256 break; 1257 1258 case ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE: 1259 1260 InfoTable = AcpiDmTableInfoPcct3; 1261 break; 1262 1263 case ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE: 1264 1265 InfoTable = AcpiDmTableInfoPcct4; 1266 break; 1267 1268 case ACPI_PCCT_TYPE_HW_REG_COMM_SUBSPACE: 1269 1270 InfoTable = AcpiDmTableInfoPcct5; 1271 break; 1272 1273 default: 1274 1275 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT"); 1276 return (AE_ERROR); 1277 } 1278 1279 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1280 if (ACPI_FAILURE (Status)) 1281 { 1282 return (Status); 1283 } 1284 1285 ParentTable = DtPeekSubtable (); 1286 DtInsertSubtable (ParentTable, Subtable); 1287 DtPopSubtable (); 1288 } 1289 1290 return (AE_OK); 1291 } 1292 1293 1294 /****************************************************************************** 1295 * 1296 * FUNCTION: DtCompilePdtt 1297 * 1298 * PARAMETERS: List - Current field list pointer 1299 * 1300 * RETURN: Status 1301 * 1302 * DESCRIPTION: Compile PDTT. 1303 * 1304 *****************************************************************************/ 1305 1306 ACPI_STATUS 1307 DtCompilePdtt ( 1308 void **List) 1309 { 1310 ACPI_STATUS Status; 1311 DT_SUBTABLE *Subtable; 1312 DT_SUBTABLE *ParentTable; 1313 DT_FIELD **PFieldList = (DT_FIELD **) List; 1314 ACPI_TABLE_PDTT *PdttHeader; 1315 UINT32 Count = 0; 1316 1317 1318 /* Main table */ 1319 1320 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt, &Subtable); 1321 if (ACPI_FAILURE (Status)) 1322 { 1323 return (Status); 1324 } 1325 1326 ParentTable = DtPeekSubtable (); 1327 DtInsertSubtable (ParentTable, Subtable); 1328 1329 PdttHeader = ACPI_CAST_PTR (ACPI_TABLE_PDTT, ParentTable->Buffer); 1330 PdttHeader->ArrayOffset = sizeof (ACPI_TABLE_PDTT); 1331 1332 /* There is only one type of subtable at this time, no need to decode */ 1333 1334 while (*PFieldList) 1335 { 1336 /* List of subchannel IDs, each 2 bytes */ 1337 1338 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt0, 1339 &Subtable); 1340 if (ACPI_FAILURE (Status)) 1341 { 1342 return (Status); 1343 } 1344 1345 DtInsertSubtable (ParentTable, Subtable); 1346 Count++; 1347 } 1348 1349 PdttHeader->TriggerCount = (UINT8) Count; 1350 return (AE_OK); 1351 } 1352 1353 1354 /****************************************************************************** 1355 * 1356 * FUNCTION: DtCompilePhat 1357 * 1358 * PARAMETERS: List - Current field list pointer 1359 * 1360 * RETURN: Status 1361 * 1362 * DESCRIPTION: Compile Phat. 1363 * 1364 *****************************************************************************/ 1365 1366 ACPI_STATUS 1367 DtCompilePhat ( 1368 void **List) 1369 { 1370 ACPI_STATUS Status = AE_OK; 1371 DT_SUBTABLE *Subtable; 1372 DT_SUBTABLE *ParentTable; 1373 DT_FIELD **PFieldList = (DT_FIELD **) List; 1374 ACPI_PHAT_HEADER *PhatHeader; 1375 ACPI_DMTABLE_INFO *Info; 1376 ACPI_PHAT_VERSION_DATA *VersionData; 1377 UINT32 DeviceDataLength; 1378 UINT32 RecordCount; 1379 DT_FIELD *DataOffsetField; 1380 DT_FIELD *DevicePathField; 1381 UINT32 TableOffset = 0; 1382 UINT32 DataOffsetValue; 1383 UINT32 i; 1384 1385 1386 /* The table consists of subtables */ 1387 1388 while (*PFieldList) 1389 { 1390 /* Compile the common subtable header */ 1391 1392 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhatHdr, &Subtable); 1393 if (ACPI_FAILURE (Status)) 1394 { 1395 return (Status); 1396 } 1397 1398 TableOffset += Subtable->Length; 1399 DbgPrint (ASL_DEBUG_OUTPUT, "0 Subtable->Length: %X\n", Subtable->Length); 1400 1401 ParentTable = DtPeekSubtable (); 1402 DtInsertSubtable (ParentTable, Subtable); 1403 DtPushSubtable (Subtable); 1404 1405 PhatHeader = ACPI_CAST_PTR (ACPI_PHAT_HEADER, Subtable->Buffer); 1406 1407 switch (PhatHeader->Type) 1408 { 1409 case ACPI_PHAT_TYPE_FW_VERSION_DATA: 1410 1411 /* Compile the middle portion of the Firmware Version Data */ 1412 1413 Info = AcpiDmTableInfoPhat0; 1414 PhatHeader->Length = sizeof (ACPI_PHAT_VERSION_DATA); 1415 DataOffsetField = NULL; 1416 break; 1417 1418 case ACPI_PHAT_TYPE_FW_HEALTH_DATA: 1419 1420 DbgPrint (ASL_DEBUG_OUTPUT, "1 Offset: %X, Name: \"%s\" Length: %X\n", 1421 (*PFieldList)->TableOffset, (*PFieldList)->Name, Subtable->Length); 1422 1423 DataOffsetField = *PFieldList; 1424 1425 /* Walk the field list to get to the "Device-specific data Offset" field */ 1426 1427 TableOffset = sizeof (ACPI_PHAT_HEALTH_DATA); 1428 for (i = 0; i < 3; i++) 1429 { 1430 DataOffsetField = DataOffsetField->Next; 1431 DbgPrint (ASL_DEBUG_OUTPUT, "2 Offset: %X, Name: \"%s\" Length: %X Value: %s:\n", 1432 TableOffset, DataOffsetField->Name, DataOffsetField->StringLength, DataOffsetField->Value); 1433 } 1434 1435 /* Convert DataOffsetField->Value (a char * string) to an integer value */ 1436 1437 sscanf (DataOffsetField->Value, "%X", &DataOffsetValue); 1438 1439 /* 1440 * Get the next field (Device Path): 1441 * DataOffsetField points to "Device-Specific Offset", next field is 1442 * "Device Path". 1443 */ 1444 DevicePathField = DataOffsetField->Next; 1445 1446 /* Compute the size of the input ASCII string as a unicode string (*2 + 2) */ 1447 1448 DevicePathField->StringLength = (strlen ((const char *) DevicePathField->Value) * 2) + 2; 1449 TableOffset += DevicePathField->StringLength; 1450 1451 DbgPrint (ASL_DEBUG_OUTPUT, "3 Offset: %X, Length: %X devicepathLength: %X\n", 1452 TableOffset, Subtable->Length, DevicePathField->StringLength); 1453 1454 /* Set the DataOffsetField to the current TableOffset */ 1455 /* Must set the DataOffsetField here (not later) */ 1456 1457 if (DataOffsetValue != 0) 1458 { 1459 snprintf (DataOffsetField->Value, Subtable->Length, "%X", TableOffset); 1460 } 1461 1462 DbgPrint (ASL_DEBUG_OUTPUT, "4 Offset: %X, Length: %X\n", TableOffset, Subtable->Length); 1463 1464 DbgPrint (ASL_DEBUG_OUTPUT, "5 TableOffset: %X, DataOffsetField->StringLength: " 1465 "%X DevicePathField Length: %X DevicePathField->Value: %s, DataOffsetField->Value: %s DataOffsetField->ByteOffset %X\n", 1466 TableOffset, DataOffsetField->StringLength, DevicePathField->StringLength, 1467 DevicePathField->Value, DataOffsetField->Value, DataOffsetField->ByteOffset); 1468 1469 /* Compile the middle portion of the Health Data Record */ 1470 1471 Info = AcpiDmTableInfoPhat1; 1472 PhatHeader->Length = sizeof (ACPI_PHAT_HEALTH_DATA); 1473 break; 1474 1475 default: 1476 1477 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT"); 1478 return (AE_ERROR); 1479 } 1480 1481 /* Compile either the Version Data or the Health Data */ 1482 1483 Status = DtCompileTable (PFieldList, Info, &Subtable); 1484 if (ACPI_FAILURE (Status)) 1485 { 1486 return (Status); 1487 } 1488 1489 DbgPrint (ASL_DEBUG_OUTPUT, "6 Offset: %X, Name: \"%s\" SubtableLength: %X\n", 1490 TableOffset /* - StartTableOffset*/, (*PFieldList)->Name, Subtable->Length); 1491 1492 ParentTable = DtPeekSubtable (); 1493 DtInsertSubtable (ParentTable, Subtable); 1494 1495 switch (PhatHeader->Type) 1496 { 1497 case ACPI_PHAT_TYPE_FW_VERSION_DATA: 1498 1499 VersionData = ACPI_CAST_PTR (ACPI_PHAT_VERSION_DATA, 1500 (Subtable->Buffer - sizeof (ACPI_PHAT_HEADER))); 1501 RecordCount = VersionData->ElementCount; 1502 1503 /* Compile all of the Version Elements */ 1504 1505 while (RecordCount) 1506 { 1507 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat0a, 1508 &Subtable); 1509 if (ACPI_FAILURE (Status)) 1510 { 1511 return (Status); 1512 } 1513 1514 ParentTable = DtPeekSubtable (); 1515 DtInsertSubtable (ParentTable, Subtable); 1516 1517 TableOffset += Subtable->Length; 1518 RecordCount--; 1519 PhatHeader->Length += sizeof (ACPI_PHAT_VERSION_ELEMENT); 1520 } 1521 1522 DtPopSubtable (); 1523 break; 1524 1525 case ACPI_PHAT_TYPE_FW_HEALTH_DATA: 1526 1527 /* Compile the Device Path */ 1528 1529 DeviceDataLength = Subtable->Length; 1530 TableOffset += Subtable->Length; 1531 1532 DbgPrint (ASL_DEBUG_OUTPUT, "7 Device Path Length: %X FieldName: \"%s\" FieldLength: " 1533 "%s FieldValue: %s SubtableLength: %X TableOffset: %X\n", DeviceDataLength, 1534 (*PFieldList)->Name, DataOffsetField->Value, (*PFieldList)->Value, 1535 Subtable->Length, TableOffset); 1536 1537 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1a, &Subtable); 1538 if (ACPI_FAILURE (Status)) 1539 { 1540 return (Status); 1541 } 1542 ParentTable = DtPeekSubtable (); 1543 DtInsertSubtable (ParentTable, Subtable); 1544 1545 /* *PFieldList will be null if previous field was at the end-of-ParseTree (EOF) */ 1546 1547 if (!*PFieldList) 1548 { 1549 DbgPrint (ASL_DEBUG_OUTPUT, "8 Exit on end-of-ParseTree\n"); 1550 return (AE_OK); 1551 } 1552 1553 DbgPrint (ASL_DEBUG_OUTPUT, "9 Device Data Length: %X FieldName: \"%s" 1554 " TableOffset: %X FieldLength: %X Field Value: %s SubtableLength: %X\n", 1555 DeviceDataLength, (*PFieldList)->Name, TableOffset, 1556 (*PFieldList)->StringLength, (*PFieldList)->Value, Subtable->Length); 1557 1558 PhatHeader->Length += (UINT16) Subtable->Length; 1559 1560 /* Convert DataOffsetField->Value (a hex char * string) to an integer value */ 1561 1562 sscanf (DataOffsetField->Value, "%X", &DataOffsetValue); 1563 1564 DbgPrint (ASL_DEBUG_OUTPUT, "10 Device-Specific Offset: %X Table Offset: %X\n", 1565 DataOffsetValue, TableOffset); 1566 if (DataOffsetValue != 0) 1567 { 1568 /* Compile Device-Specific Data - only if the Data Offset is non-zero */ 1569 1570 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1b, &Subtable); 1571 if (ACPI_FAILURE (Status)) 1572 { 1573 return (Status); 1574 } 1575 1576 DbgPrint (ASL_DEBUG_OUTPUT, "11 Subtable: %p Table Offset: %X\n", 1577 Subtable, TableOffset); 1578 if (Subtable) 1579 { 1580 DbgPrint (ASL_DEBUG_OUTPUT, "12 Device Specific Offset: " 1581 "%X FieldName \"%s\" SubtableLength %X\n", 1582 DeviceDataLength, DataOffsetField->Name, Subtable->Length); 1583 1584 DeviceDataLength += Subtable->Length; 1585 1586 ParentTable = DtPeekSubtable (); 1587 DtInsertSubtable (ParentTable, Subtable); 1588 1589 PhatHeader->Length += (UINT16) Subtable->Length; 1590 } 1591 } 1592 1593 DtPopSubtable (); 1594 1595 DbgPrint (ASL_DEBUG_OUTPUT, "13 FieldName: \"%s\" FieldLength: %X Field Value: %s\n", 1596 DataOffsetField->Name, DataOffsetField->StringLength, DataOffsetField->Value); 1597 break; 1598 1599 default: 1600 1601 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT"); 1602 return (AE_ERROR); 1603 } 1604 } 1605 1606 return (Status); 1607 } 1608 1609 1610 /****************************************************************************** 1611 * 1612 * FUNCTION: DtCompilePmtt 1613 * 1614 * PARAMETERS: List - Current field list pointer 1615 * 1616 * RETURN: Status 1617 * 1618 * DESCRIPTION: Compile PMTT. 1619 * 1620 *****************************************************************************/ 1621 1622 ACPI_STATUS 1623 DtCompilePmtt ( 1624 void **List) 1625 { 1626 ACPI_STATUS Status; 1627 DT_SUBTABLE *Subtable; 1628 DT_SUBTABLE *ParentTable; 1629 DT_FIELD **PFieldList = (DT_FIELD **) List; 1630 DT_FIELD *SubtableStart; 1631 UINT16 Type; 1632 1633 1634 /* Main table */ 1635 1636 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable); 1637 if (ACPI_FAILURE (Status)) 1638 { 1639 return (Status); 1640 } 1641 1642 ParentTable = DtPeekSubtable (); 1643 DtInsertSubtable (ParentTable, Subtable); 1644 DtPushSubtable (Subtable); 1645 1646 /* Subtables */ 1647 1648 while (*PFieldList) 1649 { 1650 SubtableStart = *PFieldList; 1651 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0); 1652 1653 switch (Type) 1654 { 1655 case ACPI_PMTT_TYPE_SOCKET: 1656 1657 /* Subtable: Socket Structure */ 1658 1659 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_SOCKET (0)\n"); 1660 1661 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0, 1662 &Subtable); 1663 if (ACPI_FAILURE (Status)) 1664 { 1665 return (Status); 1666 } 1667 1668 break; 1669 1670 case ACPI_PMTT_TYPE_CONTROLLER: 1671 1672 /* Subtable: Memory Controller Structure */ 1673 1674 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_CONTROLLER (1)\n"); 1675 1676 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1, 1677 &Subtable); 1678 if (ACPI_FAILURE (Status)) 1679 { 1680 return (Status); 1681 } 1682 1683 break; 1684 1685 case ACPI_PMTT_TYPE_DIMM: 1686 1687 /* Subtable: Physical Component (DIMM) Structure */ 1688 1689 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_DIMM (2)\n"); 1690 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2, 1691 &Subtable); 1692 if (ACPI_FAILURE (Status)) 1693 { 1694 return (Status); 1695 } 1696 1697 break; 1698 1699 case ACPI_PMTT_TYPE_VENDOR: 1700 1701 /* Subtable: Vendor-specific Structure */ 1702 1703 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_VENDOR(FF)\n"); 1704 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttVendor, 1705 &Subtable); 1706 if (ACPI_FAILURE (Status)) 1707 { 1708 return (Status); 1709 } 1710 1711 break; 1712 1713 default: 1714 1715 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT"); 1716 return (AE_ERROR); 1717 } 1718 1719 DtInsertSubtable (ParentTable, Subtable); 1720 } 1721 1722 return (Status); 1723 } 1724 1725 1726 /****************************************************************************** 1727 * 1728 * FUNCTION: DtCompilePptt 1729 * 1730 * PARAMETERS: List - Current field list pointer 1731 * 1732 * RETURN: Status 1733 * 1734 * DESCRIPTION: Compile PPTT. 1735 * 1736 *****************************************************************************/ 1737 1738 ACPI_STATUS 1739 DtCompilePptt ( 1740 void **List) 1741 { 1742 ACPI_STATUS Status; 1743 ACPI_SUBTABLE_HEADER *PpttHeader; 1744 ACPI_PPTT_PROCESSOR *PpttProcessor = NULL; 1745 DT_SUBTABLE *Subtable; 1746 DT_SUBTABLE *ParentTable; 1747 ACPI_DMTABLE_INFO *InfoTable; 1748 DT_FIELD **PFieldList = (DT_FIELD **) List; 1749 DT_FIELD *SubtableStart; 1750 ACPI_TABLE_HEADER *PpttAcpiHeader; 1751 1752 1753 ParentTable = DtPeekSubtable (); 1754 while (*PFieldList) 1755 { 1756 SubtableStart = *PFieldList; 1757 1758 /* Compile PPTT subtable header */ 1759 1760 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPpttHdr, 1761 &Subtable); 1762 if (ACPI_FAILURE (Status)) 1763 { 1764 return (Status); 1765 } 1766 DtInsertSubtable (ParentTable, Subtable); 1767 PpttHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1768 PpttHeader->Length = (UINT8)(Subtable->Length); 1769 1770 switch (PpttHeader->Type) 1771 { 1772 case ACPI_PPTT_TYPE_PROCESSOR: 1773 1774 InfoTable = AcpiDmTableInfoPptt0; 1775 break; 1776 1777 case ACPI_PPTT_TYPE_CACHE: 1778 1779 InfoTable = AcpiDmTableInfoPptt1; 1780 break; 1781 1782 case ACPI_PPTT_TYPE_ID: 1783 1784 InfoTable = AcpiDmTableInfoPptt2; 1785 break; 1786 1787 default: 1788 1789 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PPTT"); 1790 return (AE_ERROR); 1791 } 1792 1793 /* Compile PPTT subtable body */ 1794 1795 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1796 if (ACPI_FAILURE (Status)) 1797 { 1798 return (Status); 1799 } 1800 DtInsertSubtable (ParentTable, Subtable); 1801 PpttHeader->Length += (UINT8)(Subtable->Length); 1802 1803 /* Compile PPTT subtable additionals */ 1804 1805 switch (PpttHeader->Type) 1806 { 1807 case ACPI_PPTT_TYPE_PROCESSOR: 1808 1809 PpttProcessor = ACPI_SUB_PTR (ACPI_PPTT_PROCESSOR, 1810 Subtable->Buffer, sizeof (ACPI_SUBTABLE_HEADER)); 1811 if (PpttProcessor) 1812 { 1813 /* Compile initiator proximity domain list */ 1814 1815 PpttProcessor->NumberOfPrivResources = 0; 1816 while (*PFieldList) 1817 { 1818 Status = DtCompileTable (PFieldList, 1819 AcpiDmTableInfoPptt0a, &Subtable); 1820 if (ACPI_FAILURE (Status)) 1821 { 1822 return (Status); 1823 } 1824 if (!Subtable) 1825 { 1826 break; 1827 } 1828 1829 DtInsertSubtable (ParentTable, Subtable); 1830 PpttHeader->Length += (UINT8)(Subtable->Length); 1831 PpttProcessor->NumberOfPrivResources++; 1832 } 1833 } 1834 break; 1835 1836 case ACPI_PPTT_TYPE_CACHE: 1837 1838 PpttAcpiHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER, 1839 AslGbl_RootTable->Buffer); 1840 if (PpttAcpiHeader->Revision < 3) 1841 { 1842 break; 1843 } 1844 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPptt1a, 1845 &Subtable); 1846 DtInsertSubtable (ParentTable, Subtable); 1847 PpttHeader->Length += (UINT8)(Subtable->Length); 1848 break; 1849 1850 default: 1851 1852 break; 1853 } 1854 } 1855 1856 return (AE_OK); 1857 } 1858 1859 1860 /****************************************************************************** 1861 * 1862 * FUNCTION: DtCompilePrmt 1863 * 1864 * PARAMETERS: List - Current field list pointer 1865 * 1866 * RETURN: Status 1867 * 1868 * DESCRIPTION: Compile PRMT. 1869 * 1870 *****************************************************************************/ 1871 1872 ACPI_STATUS 1873 DtCompilePrmt ( 1874 void **List) 1875 { 1876 ACPI_STATUS Status; 1877 ACPI_TABLE_PRMT_HEADER *PrmtHeader; 1878 ACPI_PRMT_MODULE_INFO *PrmtModuleInfo; 1879 DT_SUBTABLE *Subtable; 1880 DT_SUBTABLE *ParentTable; 1881 DT_FIELD **PFieldList = (DT_FIELD **) List; 1882 UINT32 i, j; 1883 1884 ParentTable = DtPeekSubtable (); 1885 1886 /* Compile PRMT subtable header */ 1887 1888 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHdr, 1889 &Subtable); 1890 if (ACPI_FAILURE (Status)) 1891 { 1892 return (Status); 1893 } 1894 DtInsertSubtable (ParentTable, Subtable); 1895 PrmtHeader = ACPI_CAST_PTR (ACPI_TABLE_PRMT_HEADER, Subtable->Buffer); 1896 1897 for (i = 0; i < PrmtHeader->ModuleInfoCount; i++) 1898 { 1899 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtModule, 1900 &Subtable); 1901 if (ACPI_FAILURE (Status)) 1902 { 1903 return (Status); 1904 } 1905 DtInsertSubtable (ParentTable, Subtable); 1906 PrmtModuleInfo = ACPI_CAST_PTR (ACPI_PRMT_MODULE_INFO, Subtable->Buffer); 1907 1908 for (j = 0; j < PrmtModuleInfo->HandlerInfoCount; j++) 1909 { 1910 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHandler, 1911 &Subtable); 1912 if (ACPI_FAILURE (Status)) 1913 { 1914 return (Status); 1915 } 1916 DtInsertSubtable (ParentTable, Subtable); 1917 } 1918 } 1919 1920 return (AE_OK); 1921 } 1922 1923 1924 /****************************************************************************** 1925 * 1926 * FUNCTION: DtCompileRgrt 1927 * 1928 * PARAMETERS: List - Current field list pointer 1929 * 1930 * RETURN: Status 1931 * 1932 * DESCRIPTION: Compile RGRT. 1933 * 1934 *****************************************************************************/ 1935 1936 ACPI_STATUS 1937 DtCompileRgrt ( 1938 void **List) 1939 { 1940 ACPI_STATUS Status; 1941 DT_SUBTABLE *Subtable; 1942 DT_SUBTABLE *ParentTable; 1943 DT_FIELD **PFieldList = (DT_FIELD **) List; 1944 1945 1946 /* Compile the main table */ 1947 1948 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt, 1949 &Subtable); 1950 if (ACPI_FAILURE (Status)) 1951 { 1952 return (Status); 1953 } 1954 1955 ParentTable = DtPeekSubtable (); 1956 DtInsertSubtable (ParentTable, Subtable); 1957 1958 /* Compile the "Subtable" -- actually just the binary (PNG) image */ 1959 1960 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt0, 1961 &Subtable); 1962 if (ACPI_FAILURE (Status)) 1963 { 1964 return (Status); 1965 } 1966 1967 DtInsertSubtable (ParentTable, Subtable); 1968 return (AE_OK); 1969 } 1970 1971 1972 /****************************************************************************** 1973 * 1974 * FUNCTION: DtCompileRsdt 1975 * 1976 * PARAMETERS: List - Current field list pointer 1977 * 1978 * RETURN: Status 1979 * 1980 * DESCRIPTION: Compile RSDT. 1981 * 1982 *****************************************************************************/ 1983 1984 ACPI_STATUS 1985 DtCompileRsdt ( 1986 void **List) 1987 { 1988 DT_SUBTABLE *Subtable; 1989 DT_SUBTABLE *ParentTable; 1990 DT_FIELD *FieldList = *(DT_FIELD **) List; 1991 UINT32 Address; 1992 1993 1994 ParentTable = DtPeekSubtable (); 1995 1996 while (FieldList) 1997 { 1998 DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO); 1999 2000 DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable); 2001 DtInsertSubtable (ParentTable, Subtable); 2002 FieldList = FieldList->Next; 2003 } 2004 2005 return (AE_OK); 2006 } 2007 2008 2009 /****************************************************************************** 2010 * 2011 * FUNCTION: DtCompileS3pt 2012 * 2013 * PARAMETERS: PFieldList - Current field list pointer 2014 * 2015 * RETURN: Status 2016 * 2017 * DESCRIPTION: Compile S3PT (Pointed to by FPDT) 2018 * 2019 *****************************************************************************/ 2020 2021 ACPI_STATUS 2022 DtCompileS3pt ( 2023 DT_FIELD **PFieldList) 2024 { 2025 ACPI_STATUS Status; 2026 ACPI_FPDT_HEADER *S3ptHeader; 2027 DT_SUBTABLE *Subtable; 2028 DT_SUBTABLE *ParentTable; 2029 ACPI_DMTABLE_INFO *InfoTable; 2030 DT_FIELD *SubtableStart; 2031 2032 2033 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt, 2034 &AslGbl_RootTable); 2035 if (ACPI_FAILURE (Status)) 2036 { 2037 return (Status); 2038 } 2039 2040 DtPushSubtable (AslGbl_RootTable); 2041 2042 while (*PFieldList) 2043 { 2044 SubtableStart = *PFieldList; 2045 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr, 2046 &Subtable); 2047 if (ACPI_FAILURE (Status)) 2048 { 2049 return (Status); 2050 } 2051 2052 ParentTable = DtPeekSubtable (); 2053 DtInsertSubtable (ParentTable, Subtable); 2054 DtPushSubtable (Subtable); 2055 2056 S3ptHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer); 2057 2058 switch (S3ptHeader->Type) 2059 { 2060 case ACPI_S3PT_TYPE_RESUME: 2061 2062 InfoTable = AcpiDmTableInfoS3pt0; 2063 break; 2064 2065 case ACPI_S3PT_TYPE_SUSPEND: 2066 2067 InfoTable = AcpiDmTableInfoS3pt1; 2068 break; 2069 2070 default: 2071 2072 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT"); 2073 return (AE_ERROR); 2074 } 2075 2076 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 2077 if (ACPI_FAILURE (Status)) 2078 { 2079 return (Status); 2080 } 2081 2082 ParentTable = DtPeekSubtable (); 2083 DtInsertSubtable (ParentTable, Subtable); 2084 DtPopSubtable (); 2085 } 2086 2087 return (AE_OK); 2088 } 2089 2090 2091 /****************************************************************************** 2092 * 2093 * FUNCTION: DtCompileSdev 2094 * 2095 * PARAMETERS: List - Current field list pointer 2096 * 2097 * RETURN: Status 2098 * 2099 * DESCRIPTION: Compile SDEV. 2100 * 2101 *****************************************************************************/ 2102 2103 ACPI_STATUS 2104 DtCompileSdev ( 2105 void **List) 2106 { 2107 ACPI_STATUS Status; 2108 ACPI_SDEV_HEADER *SdevHeader; 2109 ACPI_SDEV_HEADER *SecureComponentHeader; 2110 DT_SUBTABLE *Subtable; 2111 DT_SUBTABLE *ParentTable; 2112 ACPI_DMTABLE_INFO *InfoTable; 2113 ACPI_DMTABLE_INFO *SecureComponentInfoTable = NULL; 2114 DT_FIELD **PFieldList = (DT_FIELD **) List; 2115 DT_FIELD *SubtableStart; 2116 ACPI_SDEV_PCIE *Pcie = NULL; 2117 ACPI_SDEV_NAMESPACE *Namesp = NULL; 2118 UINT32 EntryCount; 2119 ACPI_SDEV_SECURE_COMPONENT *SecureComponent = NULL; 2120 UINT16 ComponentLength = 0; 2121 2122 2123 /* Subtables */ 2124 2125 while (*PFieldList) 2126 { 2127 /* Compile common SDEV subtable header */ 2128 2129 SubtableStart = *PFieldList; 2130 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevHdr, 2131 &Subtable); 2132 if (ACPI_FAILURE (Status)) 2133 { 2134 return (Status); 2135 } 2136 2137 ParentTable = DtPeekSubtable (); 2138 DtInsertSubtable (ParentTable, Subtable); 2139 DtPushSubtable (Subtable); 2140 2141 SdevHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer); 2142 SdevHeader->Length = (UINT8)(sizeof (ACPI_SDEV_HEADER)); 2143 2144 switch (SdevHeader->Type) 2145 { 2146 case ACPI_SDEV_TYPE_NAMESPACE_DEVICE: 2147 2148 InfoTable = AcpiDmTableInfoSdev0; 2149 Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable->Buffer); 2150 SecureComponent = ACPI_CAST_PTR (ACPI_SDEV_SECURE_COMPONENT, 2151 ACPI_ADD_PTR (UINT8, Subtable->Buffer, sizeof(ACPI_SDEV_NAMESPACE))); 2152 break; 2153 2154 case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE: 2155 2156 InfoTable = AcpiDmTableInfoSdev1; 2157 Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable->Buffer); 2158 break; 2159 2160 default: 2161 2162 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV"); 2163 return (AE_ERROR); 2164 } 2165 2166 /* Compile SDEV subtable body */ 2167 2168 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 2169 if (ACPI_FAILURE (Status)) 2170 { 2171 return (Status); 2172 } 2173 2174 ParentTable = DtPeekSubtable (); 2175 DtInsertSubtable (ParentTable, Subtable); 2176 2177 /* Optional data fields are appended to the main subtable body */ 2178 2179 switch (SdevHeader->Type) 2180 { 2181 case ACPI_SDEV_TYPE_NAMESPACE_DEVICE: 2182 2183 /* 2184 * Device Id Offset will be be calculated differently depending on 2185 * the presence of secure access components. 2186 */ 2187 Namesp->DeviceIdOffset = 0; 2188 ComponentLength = 0; 2189 2190 /* If the secure access component exists, get the structures */ 2191 2192 if (SdevHeader->Flags & ACPI_SDEV_SECURE_COMPONENTS_PRESENT) 2193 { 2194 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0b, 2195 &Subtable); 2196 if (ACPI_FAILURE (Status)) 2197 { 2198 return (Status); 2199 } 2200 ParentTable = DtPeekSubtable (); 2201 DtInsertSubtable (ParentTable, Subtable); 2202 2203 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_SECURE_COMPONENT); 2204 2205 /* Compile a secure access component header */ 2206 2207 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevSecCompHdr, 2208 &Subtable); 2209 if (ACPI_FAILURE (Status)) 2210 { 2211 return (Status); 2212 } 2213 ParentTable = DtPeekSubtable (); 2214 DtInsertSubtable (ParentTable, Subtable); 2215 2216 /* Compile the secure access component */ 2217 2218 SecureComponentHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer); 2219 switch (SecureComponentHeader->Type) 2220 { 2221 case ACPI_SDEV_TYPE_ID_COMPONENT: 2222 2223 SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompId; 2224 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_ID_COMPONENT); 2225 ComponentLength = sizeof (ACPI_SDEV_ID_COMPONENT); 2226 break; 2227 2228 case ACPI_SDEV_TYPE_MEM_COMPONENT: 2229 2230 SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompMem; 2231 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_MEM_COMPONENT); 2232 ComponentLength = sizeof (ACPI_SDEV_MEM_COMPONENT); 2233 break; 2234 2235 default: 2236 2237 /* Any other secure component types are undefined */ 2238 2239 return (AE_ERROR); 2240 } 2241 2242 Status = DtCompileTable (PFieldList, SecureComponentInfoTable, 2243 &Subtable); 2244 if (ACPI_FAILURE (Status)) 2245 { 2246 return (Status); 2247 } 2248 ParentTable = DtPeekSubtable (); 2249 DtInsertSubtable (ParentTable, Subtable); 2250 2251 SecureComponent->SecureComponentOffset = 2252 sizeof (ACPI_SDEV_NAMESPACE) + sizeof (ACPI_SDEV_SECURE_COMPONENT); 2253 SecureComponent->SecureComponentLength = ComponentLength; 2254 2255 2256 /* 2257 * Add the secure component to the subtable to be added for the 2258 * the namespace subtable's length 2259 */ 2260 ComponentLength += sizeof (ACPI_SDEV_SECURE_COMPONENT); 2261 } 2262 2263 /* Append DeviceId namespace string */ 2264 2265 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0a, 2266 &Subtable); 2267 if (ACPI_FAILURE (Status)) 2268 { 2269 return (Status); 2270 } 2271 2272 if (!Subtable) 2273 { 2274 break; 2275 } 2276 2277 ParentTable = DtPeekSubtable (); 2278 DtInsertSubtable (ParentTable, Subtable); 2279 2280 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_NAMESPACE); 2281 2282 Namesp->DeviceIdLength = (UINT16) Subtable->Length; 2283 2284 /* Append Vendor data */ 2285 2286 Namesp->VendorDataLength = 0; 2287 Namesp->VendorDataOffset = 0; 2288 2289 if (*PFieldList) 2290 { 2291 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b, 2292 &Subtable); 2293 if (ACPI_FAILURE (Status)) 2294 { 2295 return (Status); 2296 } 2297 2298 if (Subtable) 2299 { 2300 ParentTable = DtPeekSubtable (); 2301 DtInsertSubtable (ParentTable, Subtable); 2302 2303 Namesp->VendorDataOffset = 2304 Namesp->DeviceIdOffset + Namesp->DeviceIdLength; 2305 Namesp->VendorDataLength = 2306 (UINT16) Subtable->Length; 2307 2308 /* Final size of entire namespace structure */ 2309 2310 SdevHeader->Length = (UINT16)(sizeof(ACPI_SDEV_NAMESPACE) + 2311 Subtable->Length + Namesp->DeviceIdLength) + ComponentLength; 2312 } 2313 } 2314 2315 break; 2316 2317 case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE: 2318 2319 /* Append the PCIe path info first */ 2320 2321 EntryCount = 0; 2322 while (*PFieldList && !strcmp ((*PFieldList)->Name, "Device")) 2323 { 2324 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1a, 2325 &Subtable); 2326 if (ACPI_FAILURE (Status)) 2327 { 2328 return (Status); 2329 } 2330 2331 if (!Subtable) 2332 { 2333 DtPopSubtable (); 2334 break; 2335 } 2336 2337 ParentTable = DtPeekSubtable (); 2338 DtInsertSubtable (ParentTable, Subtable); 2339 EntryCount++; 2340 } 2341 2342 /* Path offset will point immediately after the main subtable */ 2343 2344 Pcie->PathOffset = sizeof (ACPI_SDEV_PCIE); 2345 Pcie->PathLength = (UINT16) 2346 (EntryCount * sizeof (ACPI_SDEV_PCIE_PATH)); 2347 2348 /* Append the Vendor Data last */ 2349 2350 Pcie->VendorDataLength = 0; 2351 Pcie->VendorDataOffset = 0; 2352 2353 if (*PFieldList) 2354 { 2355 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b, 2356 &Subtable); 2357 if (ACPI_FAILURE (Status)) 2358 { 2359 return (Status); 2360 } 2361 2362 if (Subtable) 2363 { 2364 ParentTable = DtPeekSubtable (); 2365 DtInsertSubtable (ParentTable, Subtable); 2366 2367 Pcie->VendorDataOffset = 2368 Pcie->PathOffset + Pcie->PathLength; 2369 Pcie->VendorDataLength = (UINT16) 2370 Subtable->Length; 2371 } 2372 } 2373 2374 SdevHeader->Length = 2375 sizeof (ACPI_SDEV_PCIE) + 2376 Pcie->PathLength + Pcie->VendorDataLength; 2377 break; 2378 2379 default: 2380 2381 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV"); 2382 return (AE_ERROR); 2383 } 2384 2385 DtPopSubtable (); 2386 } 2387 2388 return (AE_OK); 2389 } 2390 2391 2392 /****************************************************************************** 2393 * 2394 * FUNCTION: DtCompileSlic 2395 * 2396 * PARAMETERS: List - Current field list pointer 2397 * 2398 * RETURN: Status 2399 * 2400 * DESCRIPTION: Compile SLIC. 2401 * 2402 *****************************************************************************/ 2403 2404 ACPI_STATUS 2405 DtCompileSlic ( 2406 void **List) 2407 { 2408 ACPI_STATUS Status; 2409 DT_SUBTABLE *Subtable; 2410 DT_SUBTABLE *ParentTable; 2411 DT_FIELD **PFieldList = (DT_FIELD **) List; 2412 2413 2414 while (*PFieldList) 2415 { 2416 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic, 2417 &Subtable); 2418 if (ACPI_FAILURE (Status)) 2419 { 2420 return (Status); 2421 } 2422 2423 ParentTable = DtPeekSubtable (); 2424 DtInsertSubtable (ParentTable, Subtable); 2425 DtPushSubtable (Subtable); 2426 DtPopSubtable (); 2427 } 2428 2429 return (AE_OK); 2430 } 2431 2432 2433 /****************************************************************************** 2434 * 2435 * FUNCTION: DtCompileSlit 2436 * 2437 * PARAMETERS: List - Current field list pointer 2438 * 2439 * RETURN: Status 2440 * 2441 * DESCRIPTION: Compile SLIT. 2442 * 2443 *****************************************************************************/ 2444 2445 ACPI_STATUS 2446 DtCompileSlit ( 2447 void **List) 2448 { 2449 ACPI_STATUS Status; 2450 DT_SUBTABLE *Subtable; 2451 DT_SUBTABLE *ParentTable; 2452 DT_FIELD **PFieldList = (DT_FIELD **) List; 2453 DT_FIELD *FieldList; 2454 DT_FIELD *EndOfFieldList = NULL; 2455 UINT32 Localities; 2456 UINT32 LocalityListLength; 2457 UINT8 *LocalityBuffer; 2458 2459 2460 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit, 2461 &Subtable); 2462 if (ACPI_FAILURE (Status)) 2463 { 2464 return (Status); 2465 } 2466 2467 ParentTable = DtPeekSubtable (); 2468 DtInsertSubtable (ParentTable, Subtable); 2469 2470 Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer); 2471 LocalityBuffer = UtLocalCalloc (Localities); 2472 LocalityListLength = 0; 2473 2474 /* Compile each locality buffer */ 2475 2476 FieldList = *PFieldList; 2477 while (FieldList) 2478 { 2479 DtCompileBuffer (LocalityBuffer, 2480 FieldList->Value, FieldList, Localities); 2481 2482 LocalityListLength++; 2483 DtCreateSubtable (LocalityBuffer, Localities, &Subtable); 2484 DtInsertSubtable (ParentTable, Subtable); 2485 EndOfFieldList = FieldList; 2486 FieldList = FieldList->Next; 2487 } 2488 2489 if (LocalityListLength != Localities) 2490 { 2491 sprintf(AslGbl_MsgBuffer, 2492 "Found %u entries, must match LocalityCount: %u", 2493 LocalityListLength, Localities); 2494 DtError (ASL_ERROR, ASL_MSG_ENTRY_LIST, EndOfFieldList, AslGbl_MsgBuffer); 2495 ACPI_FREE (LocalityBuffer); 2496 return (AE_LIMIT); 2497 } 2498 2499 ACPI_FREE (LocalityBuffer); 2500 return (AE_OK); 2501 } 2502 2503 2504 /****************************************************************************** 2505 * 2506 * FUNCTION: DtCompileSrat 2507 * 2508 * PARAMETERS: List - Current field list pointer 2509 * 2510 * RETURN: Status 2511 * 2512 * DESCRIPTION: Compile SRAT. 2513 * 2514 *****************************************************************************/ 2515 2516 ACPI_STATUS 2517 DtCompileSrat ( 2518 void **List) 2519 { 2520 ACPI_STATUS Status; 2521 DT_SUBTABLE *Subtable; 2522 DT_SUBTABLE *ParentTable; 2523 DT_FIELD **PFieldList = (DT_FIELD **) List; 2524 DT_FIELD *SubtableStart; 2525 ACPI_SUBTABLE_HEADER *SratHeader; 2526 ACPI_DMTABLE_INFO *InfoTable; 2527 2528 2529 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat, 2530 &Subtable); 2531 if (ACPI_FAILURE (Status)) 2532 { 2533 return (Status); 2534 } 2535 2536 ParentTable = DtPeekSubtable (); 2537 DtInsertSubtable (ParentTable, Subtable); 2538 2539 while (*PFieldList) 2540 { 2541 SubtableStart = *PFieldList; 2542 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr, 2543 &Subtable); 2544 if (ACPI_FAILURE (Status)) 2545 { 2546 return (Status); 2547 } 2548 2549 ParentTable = DtPeekSubtable (); 2550 DtInsertSubtable (ParentTable, Subtable); 2551 DtPushSubtable (Subtable); 2552 2553 SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 2554 2555 switch (SratHeader->Type) 2556 { 2557 case ACPI_SRAT_TYPE_CPU_AFFINITY: 2558 2559 InfoTable = AcpiDmTableInfoSrat0; 2560 break; 2561 2562 case ACPI_SRAT_TYPE_MEMORY_AFFINITY: 2563 2564 InfoTable = AcpiDmTableInfoSrat1; 2565 break; 2566 2567 case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: 2568 2569 InfoTable = AcpiDmTableInfoSrat2; 2570 break; 2571 2572 case ACPI_SRAT_TYPE_GICC_AFFINITY: 2573 2574 InfoTable = AcpiDmTableInfoSrat3; 2575 break; 2576 2577 case ACPI_SRAT_TYPE_GIC_ITS_AFFINITY: 2578 2579 InfoTable = AcpiDmTableInfoSrat4; 2580 break; 2581 2582 case ACPI_SRAT_TYPE_GENERIC_AFFINITY: 2583 2584 InfoTable = AcpiDmTableInfoSrat5; 2585 break; 2586 2587 case ACPI_SRAT_TYPE_GENERIC_PORT_AFFINITY: 2588 2589 InfoTable = AcpiDmTableInfoSrat6; 2590 break; 2591 2592 default: 2593 2594 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT"); 2595 return (AE_ERROR); 2596 } 2597 2598 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 2599 if (ACPI_FAILURE (Status)) 2600 { 2601 return (Status); 2602 } 2603 2604 ParentTable = DtPeekSubtable (); 2605 DtInsertSubtable (ParentTable, Subtable); 2606 DtPopSubtable (); 2607 } 2608 2609 return (AE_OK); 2610 } 2611 2612 2613 /****************************************************************************** 2614 * 2615 * FUNCTION: DtCompileStao 2616 * 2617 * PARAMETERS: PFieldList - Current field list pointer 2618 * 2619 * RETURN: Status 2620 * 2621 * DESCRIPTION: Compile STAO. 2622 * 2623 *****************************************************************************/ 2624 2625 ACPI_STATUS 2626 DtCompileStao ( 2627 void **List) 2628 { 2629 DT_FIELD **PFieldList = (DT_FIELD **) List; 2630 DT_SUBTABLE *Subtable; 2631 DT_SUBTABLE *ParentTable; 2632 ACPI_STATUS Status; 2633 2634 2635 /* Compile the main table */ 2636 2637 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao, 2638 &Subtable); 2639 if (ACPI_FAILURE (Status)) 2640 { 2641 return (Status); 2642 } 2643 2644 ParentTable = DtPeekSubtable (); 2645 DtInsertSubtable (ParentTable, Subtable); 2646 2647 /* Compile each ASCII namestring as a subtable */ 2648 2649 while (*PFieldList) 2650 { 2651 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr, 2652 &Subtable); 2653 if (ACPI_FAILURE (Status)) 2654 { 2655 return (Status); 2656 } 2657 2658 ParentTable = DtPeekSubtable (); 2659 DtInsertSubtable (ParentTable, Subtable); 2660 } 2661 2662 return (AE_OK); 2663 } 2664 2665 2666 /****************************************************************************** 2667 * 2668 * FUNCTION: DtCompileSvkl 2669 * 2670 * PARAMETERS: PFieldList - Current field list pointer 2671 * 2672 * RETURN: Status 2673 * 2674 * DESCRIPTION: Compile SVKL. 2675 * 2676 * NOTES: SVKL is essentially a flat table, with a small main table and 2677 * a variable number of a single type of subtable. 2678 * 2679 *****************************************************************************/ 2680 2681 ACPI_STATUS 2682 DtCompileSvkl ( 2683 void **List) 2684 { 2685 DT_FIELD **PFieldList = (DT_FIELD **) List; 2686 DT_SUBTABLE *Subtable; 2687 DT_SUBTABLE *ParentTable; 2688 ACPI_STATUS Status; 2689 2690 2691 /* Compile the main table */ 2692 2693 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl, 2694 &Subtable); 2695 if (ACPI_FAILURE (Status)) 2696 { 2697 return (Status); 2698 } 2699 2700 ParentTable = DtPeekSubtable (); 2701 DtInsertSubtable (ParentTable, Subtable); 2702 2703 /* Compile each subtable */ 2704 2705 while (*PFieldList) 2706 { 2707 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl0, 2708 &Subtable); 2709 if (ACPI_FAILURE (Status)) 2710 { 2711 return (Status); 2712 } 2713 2714 ParentTable = DtPeekSubtable (); 2715 DtInsertSubtable (ParentTable, Subtable); 2716 } 2717 2718 return (AE_OK); 2719 } 2720 2721 2722 /****************************************************************************** 2723 * 2724 * FUNCTION: DtCompileTcpa 2725 * 2726 * PARAMETERS: PFieldList - Current field list pointer 2727 * 2728 * RETURN: Status 2729 * 2730 * DESCRIPTION: Compile TCPA. 2731 * 2732 *****************************************************************************/ 2733 2734 ACPI_STATUS 2735 DtCompileTcpa ( 2736 void **List) 2737 { 2738 DT_FIELD **PFieldList = (DT_FIELD **) List; 2739 DT_SUBTABLE *Subtable; 2740 ACPI_TABLE_TCPA_HDR *TcpaHeader; 2741 DT_SUBTABLE *ParentTable; 2742 ACPI_STATUS Status; 2743 2744 2745 /* Compile the main table */ 2746 2747 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr, 2748 &Subtable); 2749 if (ACPI_FAILURE (Status)) 2750 { 2751 return (Status); 2752 } 2753 2754 ParentTable = DtPeekSubtable (); 2755 DtInsertSubtable (ParentTable, Subtable); 2756 2757 /* 2758 * Examine the PlatformClass field to determine the table type. 2759 * Either a client or server table. Only one. 2760 */ 2761 TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer); 2762 2763 switch (TcpaHeader->PlatformClass) 2764 { 2765 case ACPI_TCPA_CLIENT_TABLE: 2766 2767 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient, 2768 &Subtable); 2769 break; 2770 2771 case ACPI_TCPA_SERVER_TABLE: 2772 2773 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer, 2774 &Subtable); 2775 break; 2776 2777 default: 2778 2779 AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n", 2780 TcpaHeader->PlatformClass); 2781 Status = AE_ERROR; 2782 break; 2783 } 2784 2785 ParentTable = DtPeekSubtable (); 2786 DtInsertSubtable (ParentTable, Subtable); 2787 return (Status); 2788 } 2789 2790 2791 /****************************************************************************** 2792 * 2793 * FUNCTION: DtCompileTpm2Rev3 2794 * 2795 * PARAMETERS: PFieldList - Current field list pointer 2796 * 2797 * RETURN: Status 2798 * 2799 * DESCRIPTION: Compile TPM2 revision 3 2800 * 2801 *****************************************************************************/ 2802 static ACPI_STATUS 2803 DtCompileTpm2Rev3 ( 2804 void **List) 2805 { 2806 DT_FIELD **PFieldList = (DT_FIELD **) List; 2807 DT_SUBTABLE *Subtable; 2808 ACPI_TABLE_TPM23 *Tpm23Header; 2809 DT_SUBTABLE *ParentTable; 2810 ACPI_STATUS Status = AE_OK; 2811 2812 2813 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23, 2814 &Subtable); 2815 2816 ParentTable = DtPeekSubtable (); 2817 DtInsertSubtable (ParentTable, Subtable); 2818 Tpm23Header = ACPI_CAST_PTR (ACPI_TABLE_TPM23, ParentTable->Buffer); 2819 2820 /* Subtable type depends on the StartMethod */ 2821 2822 switch (Tpm23Header->StartMethod) 2823 { 2824 case ACPI_TPM23_ACPI_START_METHOD: 2825 2826 /* Subtable specific to to ARM_SMC */ 2827 2828 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23a, 2829 &Subtable); 2830 if (ACPI_FAILURE (Status)) 2831 { 2832 return (Status); 2833 } 2834 2835 ParentTable = DtPeekSubtable (); 2836 DtInsertSubtable (ParentTable, Subtable); 2837 break; 2838 2839 default: 2840 break; 2841 } 2842 2843 return (Status); 2844 } 2845 2846 2847 /****************************************************************************** 2848 * 2849 * FUNCTION: DtCompileTpm2 2850 * 2851 * PARAMETERS: PFieldList - Current field list pointer 2852 * 2853 * RETURN: Status 2854 * 2855 * DESCRIPTION: Compile TPM2. 2856 * 2857 *****************************************************************************/ 2858 2859 ACPI_STATUS 2860 DtCompileTpm2 ( 2861 void **List) 2862 { 2863 DT_FIELD **PFieldList = (DT_FIELD **) List; 2864 DT_SUBTABLE *Subtable; 2865 ACPI_TABLE_TPM2 *Tpm2Header; 2866 DT_SUBTABLE *ParentTable; 2867 ACPI_STATUS Status = AE_OK; 2868 ACPI_TABLE_HEADER *Header; 2869 2870 2871 ParentTable = DtPeekSubtable (); 2872 2873 Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 2874 2875 if (Header->Revision == 3) 2876 { 2877 return (DtCompileTpm2Rev3 (List)); 2878 } 2879 2880 /* Compile the main table */ 2881 2882 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2, 2883 &Subtable); 2884 if (ACPI_FAILURE (Status)) 2885 { 2886 return (Status); 2887 } 2888 2889 ParentTable = DtPeekSubtable (); 2890 DtInsertSubtable (ParentTable, Subtable); 2891 2892 Tpm2Header = ACPI_CAST_PTR (ACPI_TABLE_TPM2, ParentTable->Buffer); 2893 2894 /* Method parameters */ 2895 /* Optional: Log area minimum length */ 2896 /* Optional: Log area start address */ 2897 /* TBD: Optional fields above not fully implemented (not optional at this time) */ 2898 2899 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2a, 2900 &Subtable); 2901 if (ACPI_FAILURE (Status)) 2902 { 2903 return (Status); 2904 } 2905 2906 ParentTable = DtPeekSubtable (); 2907 DtInsertSubtable (ParentTable, Subtable); 2908 2909 2910 /* Subtable type depends on the StartMethod */ 2911 2912 switch (Tpm2Header->StartMethod) 2913 { 2914 case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC: 2915 2916 /* Subtable specific to to ARM_SMC */ 2917 2918 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm211, 2919 &Subtable); 2920 if (ACPI_FAILURE (Status)) 2921 { 2922 return (Status); 2923 } 2924 2925 ParentTable = DtPeekSubtable (); 2926 DtInsertSubtable (ParentTable, Subtable); 2927 break; 2928 2929 case ACPI_TPM2_START_METHOD: 2930 case ACPI_TPM2_MEMORY_MAPPED: 2931 case ACPI_TPM2_COMMAND_BUFFER: 2932 case ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD: 2933 break; 2934 2935 case ACPI_TPM2_RESERVED1: 2936 case ACPI_TPM2_RESERVED3: 2937 case ACPI_TPM2_RESERVED4: 2938 case ACPI_TPM2_RESERVED5: 2939 case ACPI_TPM2_RESERVED9: 2940 case ACPI_TPM2_RESERVED10: 2941 2942 AcpiOsPrintf ("\n**** Reserved TPM2 Start Method type 0x%X\n", 2943 Tpm2Header->StartMethod); 2944 Status = AE_ERROR; 2945 break; 2946 2947 case ACPI_TPM2_NOT_ALLOWED: 2948 default: 2949 2950 AcpiOsPrintf ("\n**** Unknown TPM2 Start Method type 0x%X\n", 2951 Tpm2Header->StartMethod); 2952 Status = AE_ERROR; 2953 break; 2954 } 2955 2956 return (Status); 2957 } 2958 2959 2960 /****************************************************************************** 2961 * 2962 * FUNCTION: DtGetGenericTableInfo 2963 * 2964 * PARAMETERS: Name - Generic type name 2965 * 2966 * RETURN: Info entry 2967 * 2968 * DESCRIPTION: Obtain table info for a generic name entry 2969 * 2970 *****************************************************************************/ 2971 2972 ACPI_DMTABLE_INFO * 2973 DtGetGenericTableInfo ( 2974 char *Name) 2975 { 2976 ACPI_DMTABLE_INFO *Info; 2977 UINT32 i; 2978 2979 2980 if (!Name) 2981 { 2982 return (NULL); 2983 } 2984 2985 /* Search info table for name match */ 2986 2987 for (i = 0; ; i++) 2988 { 2989 Info = AcpiDmTableInfoGeneric[i]; 2990 if (Info->Opcode == ACPI_DMT_EXIT) 2991 { 2992 Info = NULL; 2993 break; 2994 } 2995 2996 /* Use caseless compare for generic keywords */ 2997 2998 if (!AcpiUtStricmp (Name, Info->Name)) 2999 { 3000 break; 3001 } 3002 } 3003 3004 return (Info); 3005 } 3006 3007 3008 /****************************************************************************** 3009 * 3010 * FUNCTION: DtCompileUefi 3011 * 3012 * PARAMETERS: List - Current field list pointer 3013 * 3014 * RETURN: Status 3015 * 3016 * DESCRIPTION: Compile UEFI. 3017 * 3018 *****************************************************************************/ 3019 3020 ACPI_STATUS 3021 DtCompileUefi ( 3022 void **List) 3023 { 3024 ACPI_STATUS Status; 3025 DT_SUBTABLE *Subtable; 3026 DT_SUBTABLE *ParentTable; 3027 DT_FIELD **PFieldList = (DT_FIELD **) List; 3028 UINT16 *DataOffset; 3029 3030 3031 /* Compile the predefined portion of the UEFI table */ 3032 3033 Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi, 3034 &Subtable); 3035 if (ACPI_FAILURE (Status)) 3036 { 3037 return (Status); 3038 } 3039 3040 DataOffset = (UINT16 *) (Subtable->Buffer + 16); 3041 *DataOffset = sizeof (ACPI_TABLE_UEFI); 3042 3043 ParentTable = DtPeekSubtable (); 3044 DtInsertSubtable (ParentTable, Subtable); 3045 3046 /* 3047 * Compile the "generic" portion of the UEFI table. This 3048 * part of the table is not predefined and any of the generic 3049 * operators may be used. 3050 */ 3051 DtCompileGeneric ((void **) PFieldList, NULL, NULL); 3052 return (AE_OK); 3053 } 3054 3055 3056 /****************************************************************************** 3057 * 3058 * FUNCTION: DtCompileViot 3059 * 3060 * PARAMETERS: List - Current field list pointer 3061 * 3062 * RETURN: Status 3063 * 3064 * DESCRIPTION: Compile VIOT. 3065 * 3066 *****************************************************************************/ 3067 3068 ACPI_STATUS 3069 DtCompileViot ( 3070 void **List) 3071 { 3072 ACPI_STATUS Status; 3073 DT_SUBTABLE *Subtable; 3074 DT_SUBTABLE *ParentTable; 3075 DT_FIELD **PFieldList = (DT_FIELD **) List; 3076 DT_FIELD *SubtableStart; 3077 ACPI_TABLE_VIOT *Viot; 3078 ACPI_VIOT_HEADER *ViotHeader; 3079 ACPI_DMTABLE_INFO *InfoTable; 3080 UINT16 NodeCount; 3081 3082 ParentTable = DtPeekSubtable (); 3083 3084 Status = DtCompileTable (PFieldList, AcpiDmTableInfoViot, &Subtable); 3085 if (ACPI_FAILURE (Status)) 3086 { 3087 return (Status); 3088 } 3089 DtInsertSubtable (ParentTable, Subtable); 3090 3091 /* 3092 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care 3093 * should be taken to avoid accessing ACPI_TABLE_HEADER fields. 3094 */ 3095 Viot = ACPI_SUB_PTR (ACPI_TABLE_VIOT, Subtable->Buffer, 3096 sizeof (ACPI_TABLE_HEADER)); 3097 3098 Viot->NodeOffset = sizeof (ACPI_TABLE_VIOT); 3099 3100 NodeCount = 0; 3101 while (*PFieldList) { 3102 SubtableStart = *PFieldList; 3103 Status = DtCompileTable (PFieldList, AcpiDmTableInfoViotHeader, 3104 &Subtable); 3105 if (ACPI_FAILURE (Status)) 3106 { 3107 return (Status); 3108 } 3109 3110 ParentTable = DtPeekSubtable (); 3111 DtInsertSubtable (ParentTable, Subtable); 3112 DtPushSubtable (Subtable); 3113 3114 ViotHeader = ACPI_CAST_PTR (ACPI_VIOT_HEADER, Subtable->Buffer); 3115 3116 switch (ViotHeader->Type) 3117 { 3118 case ACPI_VIOT_NODE_PCI_RANGE: 3119 3120 InfoTable = AcpiDmTableInfoViot1; 3121 break; 3122 3123 case ACPI_VIOT_NODE_MMIO: 3124 3125 InfoTable = AcpiDmTableInfoViot2; 3126 break; 3127 3128 case ACPI_VIOT_NODE_VIRTIO_IOMMU_PCI: 3129 3130 InfoTable = AcpiDmTableInfoViot3; 3131 break; 3132 3133 case ACPI_VIOT_NODE_VIRTIO_IOMMU_MMIO: 3134 3135 InfoTable = AcpiDmTableInfoViot4; 3136 break; 3137 3138 default: 3139 3140 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "VIOT"); 3141 return (AE_ERROR); 3142 } 3143 3144 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 3145 if (ACPI_FAILURE (Status)) 3146 { 3147 return (Status); 3148 } 3149 3150 ParentTable = DtPeekSubtable (); 3151 DtInsertSubtable (ParentTable, Subtable); 3152 DtPopSubtable (); 3153 NodeCount++; 3154 } 3155 3156 Viot->NodeCount = NodeCount; 3157 return (AE_OK); 3158 } 3159 3160 3161 /****************************************************************************** 3162 * 3163 * FUNCTION: DtCompileWdat 3164 * 3165 * PARAMETERS: List - Current field list pointer 3166 * 3167 * RETURN: Status 3168 * 3169 * DESCRIPTION: Compile WDAT. 3170 * 3171 *****************************************************************************/ 3172 3173 ACPI_STATUS 3174 DtCompileWdat ( 3175 void **List) 3176 { 3177 ACPI_STATUS Status; 3178 3179 3180 Status = DtCompileTwoSubtables (List, 3181 AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0); 3182 return (Status); 3183 } 3184 3185 3186 /****************************************************************************** 3187 * 3188 * FUNCTION: DtCompileWpbt 3189 * 3190 * PARAMETERS: List - Current field list pointer 3191 * 3192 * RETURN: Status 3193 * 3194 * DESCRIPTION: Compile WPBT. 3195 * 3196 *****************************************************************************/ 3197 3198 ACPI_STATUS 3199 DtCompileWpbt ( 3200 void **List) 3201 { 3202 DT_FIELD **PFieldList = (DT_FIELD **) List; 3203 DT_SUBTABLE *Subtable; 3204 DT_SUBTABLE *ParentTable; 3205 ACPI_TABLE_WPBT *Table; 3206 ACPI_STATUS Status; 3207 3208 3209 /* Compile the main table */ 3210 3211 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt, &Subtable); 3212 if (ACPI_FAILURE (Status)) 3213 { 3214 return (Status); 3215 } 3216 3217 ParentTable = DtPeekSubtable (); 3218 DtInsertSubtable (ParentTable, Subtable); 3219 Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer); 3220 3221 /* 3222 * Exit now if there are no arguments specified. This is indicated by: 3223 * The "Command-line Arguments" field has not been specified (if specified, 3224 * it will be the last field in the field list -- after the main table). 3225 * Set the Argument Length in the main table to zero. 3226 */ 3227 if (!*PFieldList) 3228 { 3229 Table->ArgumentsLength = 0; 3230 return (AE_OK); 3231 } 3232 3233 /* Compile the argument list subtable */ 3234 3235 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0, &Subtable); 3236 if (ACPI_FAILURE (Status)) 3237 { 3238 return (Status); 3239 } 3240 3241 /* Extract the length of the Arguments buffer, insert into main table */ 3242 3243 Table->ArgumentsLength = (UINT16) Subtable->TotalLength; 3244 DtInsertSubtable (ParentTable, Subtable); 3245 return (AE_OK); 3246 } 3247 3248 3249 /****************************************************************************** 3250 * 3251 * FUNCTION: DtCompileXsdt 3252 * 3253 * PARAMETERS: List - Current field list pointer 3254 * 3255 * RETURN: Status 3256 * 3257 * DESCRIPTION: Compile XSDT. 3258 * 3259 *****************************************************************************/ 3260 3261 ACPI_STATUS 3262 DtCompileXsdt ( 3263 void **List) 3264 { 3265 DT_SUBTABLE *Subtable; 3266 DT_SUBTABLE *ParentTable; 3267 DT_FIELD *FieldList = *(DT_FIELD **) List; 3268 UINT64 Address; 3269 3270 3271 ParentTable = DtPeekSubtable (); 3272 3273 while (FieldList) 3274 { 3275 DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO); 3276 3277 DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable); 3278 DtInsertSubtable (ParentTable, Subtable); 3279 FieldList = FieldList->Next; 3280 } 3281 3282 return (AE_OK); 3283 } 3284 3285 3286 /****************************************************************************** 3287 * 3288 * FUNCTION: DtCompileGeneric 3289 * 3290 * PARAMETERS: List - Current field list pointer 3291 * Name - Field name to end generic compiling 3292 * Length - Compiled table length to return 3293 * 3294 * RETURN: Status 3295 * 3296 * DESCRIPTION: Compile generic unknown table. 3297 * 3298 *****************************************************************************/ 3299 3300 ACPI_STATUS 3301 DtCompileGeneric ( 3302 void **List, 3303 char *Name, 3304 UINT32 *Length) 3305 { 3306 ACPI_STATUS Status; 3307 DT_SUBTABLE *Subtable; 3308 DT_SUBTABLE *ParentTable; 3309 DT_FIELD **PFieldList = (DT_FIELD **) List; 3310 ACPI_DMTABLE_INFO *Info; 3311 3312 3313 ParentTable = DtPeekSubtable (); 3314 3315 /* 3316 * Compile the "generic" portion of the table. This 3317 * part of the table is not predefined and any of the generic 3318 * operators may be used. 3319 */ 3320 3321 /* Find any and all labels in the entire generic portion */ 3322 3323 DtDetectAllLabels (*PFieldList); 3324 3325 /* Now we can actually compile the parse tree */ 3326 3327 if (Length && *Length) 3328 { 3329 *Length = 0; 3330 } 3331 while (*PFieldList) 3332 { 3333 if (Name && !strcmp ((*PFieldList)->Name, Name)) 3334 { 3335 break; 3336 } 3337 3338 Info = DtGetGenericTableInfo ((*PFieldList)->Name); 3339 if (!Info) 3340 { 3341 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found", 3342 (*PFieldList)->Name); 3343 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 3344 (*PFieldList), AslGbl_MsgBuffer); 3345 3346 *PFieldList = (*PFieldList)->Next; 3347 continue; 3348 } 3349 3350 Status = DtCompileTable (PFieldList, Info, 3351 &Subtable); 3352 if (ACPI_SUCCESS (Status)) 3353 { 3354 DtInsertSubtable (ParentTable, Subtable); 3355 if (Length) 3356 { 3357 *Length += Subtable->Length; 3358 } 3359 } 3360 else 3361 { 3362 *PFieldList = (*PFieldList)->Next; 3363 3364 if (Status == AE_NOT_FOUND) 3365 { 3366 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found", 3367 (*PFieldList)->Name); 3368 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 3369 (*PFieldList), AslGbl_MsgBuffer); 3370 } 3371 } 3372 } 3373 3374 return (AE_OK); 3375 } 3376