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