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